数据结构与算法实验题7.1 M 商人的求救
问题描述:
A 国正面临着一场残酷的战争,城市被支持不同领导的两股势力占据,作为一个商人,M
先生并不太关心政治,但是他知道局势很严重,他希望你能救他出去。
M 先生说:“为了安全起见,我们的路线最多只能包含一条连接两股不同势力城市的道
路”。M 先生想知道最快多久能到达目的地。
数据输入:
第一行N(2<=N<=600),代表城市个数。第二行M(0<=M<=10000),代表道路条数。
接下来M 行每行三个数A,B,T。代表一条从城市A 到城市B 的路(双向边)需要耗时
T(1<=T<=1500)。
接下来一行N 个数,这些数只会是1 或者2,第i 个数字代表第i 个城市属于第几股势
力。
为了简化问题,我们假设开始时M 先生在城市1,目的地是城市2,城市1 属于第1 股
势力,城市2 属于第2 股势力。
道路是双向的。数据保证没有重边。
结果输出:
输出最少需要的时间。如果无法到达则输出-1。
输入示例: 输出示例:
2
1
1 2 100
1 2
100
3
3
1 2 100
1 3 40
2 3 50
1 2 1
90
5
5
3 1 200
5 3 150
2 5 160
4 3 170
4 2 170
1 2 2 2 1
540
并查集+dijstra算法
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #define inf 0xffffff 5 int g[601][601]; 6 struct ufs 7 { 8 int parent[1000]; 9 }u; 10 int find(int e) 11 { 12 if(e!=u.parent[e]) 13 u.parent[e]=find(u.parent[e]); 14 return u.parent[e]; 15 } 16 void funion(int i,int j) 17 { 18 u.parent[i]=j; 19 } 20 void dijstra(int n) 21 { 22 int lowcost[601],used[601],min,i,j,k; 23 memset(used,0,sizeof(used)); 24 for(i=1;i<=n;i++) 25 lowcost[i]=g[i][1]; 26 used[1]=1; 27 for(i=1;i<n;i++) 28 { 29 j=1; 30 min=inf; 31 for(k=2;k<=n;k++) 32 { 33 if(lowcost[k]<min&&!used[k]) 34 min=lowcost[k], 35 j=k; 36 } 37 used[j]=1; 38 for(k=2;k<=n;k++) 39 { 40 int t1=find(k),t2=find(j),t3=find(1); 41 if(t1==t3&&t2!=t1)//横跨两股势力 42 { 43 } 44 else 45 { 46 if(g[k][j]+lowcost[j]<lowcost[k]&&!used[k]) 47 lowcost[k]=g[k][1]=g[1][k]=g[k][j]+lowcost[j]; 48 } 49 } 50 } 51 } 52 int main() 53 { 54 int n,m,i,a,b,j,t; 55 scanf("%d %d",&n,&m); 56 for(i=1;i<=n;i++) 57 u.parent[i]=i; 58 for(i=1;i<=n;i++) 59 { 60 for(j=1;j<=n;j++) 61 g[i][j]=inf; 62 g[i][i]=0; 63 } 64 for(i=1;i<=m;i++) 65 { 66 scanf("%d %d %d",&a,&b,&t); 67 g[a][b]=g[b][a]=t; 68 } 69 for(i=1;i<=n;i++) 70 { 71 scanf("%d",&a); 72 if(a==1) 73 funion(i,1); 74 else if(a==2) 75 funion(i,2); 76 } 77 dijstra(n); 78 if(g[1][2]==inf) 79 printf("-1\n"); 80 else 81 printf("%d\n",g[1][2]); 82 83 return 0; 84 }
5910 | 031202110 | M.cpp | AC|AC|AC|AC|AC|AC|AC|AC|AC|AC| | 77MS | 1660KB |