【PAT顶级】1001 Battle Over Cities - Hard Version (35分)(最小生成树Prim算法)
题意:输入两个正整数N(<=500)和M,分别表示图中点的数量和边的数量,接着输入M行,每行包括四个数,分别代表一条边的两个端点和修通这条路的花费以及标识符,标识符为1说明这条路畅通,标识符为0说明这条路不能使用。如果这张图中其中一个点失效,那么所有和这个点连接的路径都会不能使用(且因为这个点的失效,这条路无法修通),此时需要修通一些(可能不需要修通)路径试得剩余N-1个点联通。如果有多个这样的点,以序号升序输出,没有则输出0。
AAAAAccepted code:
1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 int dis[507][507]; 5 int res[507]; 6 bool vis[507]; 7 int n,m; 8 int d[507]; 9 void mst(int v){ 10 memset(vis,0,sizeof(vis)); 11 int s=1+v;//以失效的点的下一个点作为起点 12 if(s>n) 13 s=1;//失效点为n的时候,以1为起点 14 for(int i=1;i<=n;++i) 15 d[i]=dis[i][s]; 16 vis[v]=vis[s]=1; 17 int nex=0; 18 int num=n-2;//去掉失效点和起点一共有n-2个点 19 while(num--){ 20 int mn=1e9; 21 for(int i=1;i<=n;++i) 22 if(!vis[i]&&mn>d[i]){ 23 mn=d[i]; 24 nex=i; 25 } 26 if(mn==1e9){ 27 res[v]=1e9; 28 break; 29 } 30 res[v]+=mn; 31 vis[nex]=1; 32 for(int i=1;i<=n;++i) 33 if(!vis[i]&&d[i]>dis[i][nex])//更新未被访问过的点到已经加入集合中的点的最短路径 34 d[i]=dis[i][nex]; 35 } 36 } 37 int main(){ 38 ios::sync_with_stdio(false); 39 cin.tie(NULL); 40 cout.tie(NULL); 41 for(int i=1;i<=500;++i) 42 for(int j=1;j<=500;++j) 43 dis[i][j]=1e9; 44 cin>>n>>m; 45 for(int i=1;i<=m;++i){ 46 int c1,c2,cost,status; 47 cin>>c1>>c2>>cost>>status; 48 if(status==0) 49 dis[c1][c2]=dis[c2][c1]=cost; 50 else 51 dis[c1][c2]=dis[c2][c1]=0; 52 } 53 int mx=0; 54 for(int i=1;i<=n;++i){ 55 mst(i); 56 mx=max(mx,res[i]); 57 } 58 if(mx==0) 59 cout<<0; 60 else{ 61 int flag=0; 62 for(int i=1;i<=n;++i){ 63 if(flag&&res[i]==mx) 64 cout<<" "<<i; 65 else if(res[i]==mx){ 66 cout<<i; 67 flag=1; 68 } 69 } 70 } 71 return 0; 72 }
保持热爱 不懈努力
不试试看怎么知道会失败呢(划掉)
世上无难事 只要肯放弃(划掉)