1376:信使(msner)
時間限制: 1000 ms 內存限制: 65536 KB
提交數: 4971 通過數: 2323
【題目描述】
戰爭時期,前線有n個哨所,每個哨所可能會與其他若干個哨所之間有通信聯繫。信使負責在哨所之間傳遞信息,當然,這是要花費一定時間的(以天爲單位)。指揮部設在第一個哨所。當指揮部下達一個命令後,指揮部就派出若干個信使向與指揮部相連的哨所送信。當一個哨所接到信後,這個哨所內的信使們也以同樣的方式向其他哨所送信。直至所有n個哨所全部接到命令後,送信纔算成功。因爲準備充足,每個哨所內都安排了足夠的信使(如果一個哨所與其他k個哨所有通信聯繫的話,這個哨所內至少會配備k個信使)。
現在總指揮請你編一個程序,計算出完成整個送信過程最短需要多少時間。
【輸入】
第1行有兩個整數n和m,中間用1個空格隔開,分別表示有n個哨所和m條通信線路,且1≤n≤100。
第2至m+1行:每行三個整數i、j、k,中間用1個空格隔開,表示第i個和第j個哨所之間存在通信線路,且這條線路要花費k天。
【輸出】
一個整數,表示完成整個送信過程的最短時間。如果不是所有的哨所都能收到信,就輸出-1。
【輸入樣例】
4 4
1 2 4
2 3 7
2 4 1
3 4 6
【輸出樣例】
11
1 floyed算法
1)算法思路:在圖中求最短路還是要分開說的,分別是單源最短路和多源最短路,而floyed算法是求多源最短路的,什麼是多源最短路呢?簡單來說就是用完算法之後能直接寫出任意兩點間的最短路徑長度。floyed算法在本質上是動態規劃思想,不斷更新最短路徑的值,主要思想就是不斷判斷兩個點是否可以通過一個點中繼以刷新當前兩個點最短路徑的估計值,直到每兩個點都判斷完成。如下圖例:
2、dijkstra算法:思想及其功效:dijkstra算法屬於單源最短路算法,簡單說就是用過之後,只能直接寫出一點到其他任意一點的最短路徑長度。這個算法類似於prim算法,找出刷新點所能到達的點,然後再繼續刷新。
void dijkstra()
{
vis[1]==0;dis[1]=0;
for(int i=1;i<=n-1;i++)
{
minn=inf;
for(int j=1;j<=n;j++)
{
if(vis[j]==0&&dis[j]<minn)
{
k=j;
minn=dis[j];
}
}
vis[k]=1;
for(int j=1;j<=n;j++)
{
if(dis[j]>dis[k]+map[k][j]&&map[k][j]<inf)
dis[j]=dis[k]+map[k][j];
}
}
}
3 SPFA
圖的權值有正的,當然也有負的,對於負邊 SPFA能處理負權邊。思路和dijkstra有點像。
void SPFA()
{
for(int i=1;i<=n;i++)
dis[i]=inf;
queue<int>q;
q.push(1);vis[1]=1;dis[1]=0;
while(q.size())
{
x=q.front();q.pop();vis[x]=0;
for(int i=head[x];i;i=a[i].next)
{
int s=a[i].to;
if(dis[s]>dis[x]+a[i].cost)
{
dis[s]=dis[x]+a[i].cost;
if(vis[s]==0)
{
vis[s]=1;
q.push(s);
}
}
}
}
}
1 floyed算法
#include<cstdio>
#include<iostream>
using namespace std;
int a[1000][1000],n,m,d,b,c;
int maxn = -1;
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
a[i][j] = 999999;
for(int i = 1; i <= m; i++)
{
cin >> d >> b >> c;
a[d][b] = c;
a[b][d] = c;
}
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(a[i][j] > a[i][k] + a[k][j] )
{
a[i][j] = a[i][k] +a[k][j];
}
}
for(int i = 1; i <= n; i++)
{
if(maxn <a[1][i])
maxn = a[1][i];
}
cout << maxn;
return 0;
}
dijkstra算法:
#include<cstdio>
#include<iostream>
#define INF 0X3F3F3F3F
using namespace std;
int n,m,map[1000][1000],dis[1000],vis[1000];
int a,b,maxn = -1,minn,k;
inline void dijkstra(){
vis[1] = 0;
dis[1] =0;
for(int i = 1; i <= n; i++)
{
minn = INF;
for(int j = 1; j <=n; j++)
{
if(!vis[j] && dis[j] < minn)
{
k = j;
minn = dis[j];
}
}
vis[k] =1;
for(int j =1; j <= n;j++)
{
if(dis[j] > dis[k] + map[k][j] && map[k][j] < INF)
dis[j] = dis[k] + map[k][j];
}
}
}
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
map[i][j] = INF;
dis[i] = INF;
}
for(int i = 1; i <= m; i++)
{
cin >> a >> b;
cin >> map[a][b];
map[b][a] = map[a][b];
}
dijkstra();
for(int i = 1; i <= n; i++)
{
if(dis[i] > maxn)
maxn = dis[i];
}
cout << maxn;
return 0;
}
SPFA算法
#include<cstdio>
#include<iostream>
#include<queue>
#define INF 0x3f3f3f3f
#define N 1000
using namespace std;
struct map{
int from;
int to;
int cost;
int next;
}a[N];
int head[N],dis[N],vis[N],n,m,maxn = -1,x,cnt,a1,b1,c1;
void add(int from, int to, int cost){
a[++cnt].to = to;
a[cnt].cost = cost;
a[cnt].next = head[from];
head[from] = cnt;
}
void SPFA(){
for(int i = 1; i <= n; i++)
dis[i] = INF;
queue<int> q;
q.push(1);
vis[1] = 1;
dis[1] = 0;
while(q.size()){
x = q.front();
q.pop();
vis[x] = 0;
for(int i = head[x];i;i = a[i].next){
int s = a[i].to;
if(dis[s] > dis[x] + a[i].cost)
{
dis[s] = dis[x] + a[i].cost;
if(vis[s] == 0)
{
vis[s] = 1;
q.push(s);
}
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d",&a1,&b1,&c1);
add(a1,b1,c1);
add(b1,a1,c1);
}
SPFA();
for(int i = 2; i <= n; i++)
if(dis[i] > maxn && dis[i] != INF)
maxn = dis[i];
printf("%d",maxn);
return 0;
}