/*次小生成树 题意:给你一些路径,现在将一部分路径权值减少后问是否可以替代最小生成树里面的边。 解:次小生成树,即将这条边连上,构成一个环 求出任意两点路径之间的除了这条边的最大值,比较这个最大值>=这条边,说明可以替换。 prime算法次小生成树模板 */ #include<stdio.h> #include<string.h> #define N 1100 #define inf 0x3fffffff int ma[N][N]; int Min(int a,int b) { return a>b?b:a; } int Max(int a,int b) { return a>b?a:b; } struct node { int u,v,w; }bian[N*100]; int maxd[N][N],n; void prime() { int i,j,dis[N],vis[N],pre[N],stac[N],top=0; memset(maxd,-1,sizeof(maxd)); for(i=1;i<=n;i++) {//初始化 dis[i]=ma[1][i]; pre[i]=1; } stac[top++]=1;//储存最小生成树的点 memset(vis,0,sizeof(vis)); vis[1]=1; for(i=1;i<n;i++) { int minn=inf,next=1; for(j=1;j<=n;j++) if(!vis[j]&&minn>dis[j]) {//找到最近的 minn=dis[j]; next=j; } vis[next]=1; //printf("%d\n",minn); for(j=0;j<top;j++) maxd[next][stac[j]]=maxd[stac[j]][next]=Max(minn,maxd[pre[next]][stac[j]]);//当前点与栈里面的点的最大值为minn和他的父节点与其他点的权值最大值 stac[top++]=next;//加入栈 for(j=1;j<=n;j++) if(!vis[j]&&dis[j]>ma[next][j]) {//更新距离 pre[j]=next;//与j连接的最近的点即为他的父节点 dis[j]=ma[next][j]; } } return ; } int main(){ int m,i,j,a,b,c,q; while(scanf("%d%d%d",&n,&m,&q)!=EOF) { for(i=1;i<=n;i++) { ma[i][i]=0; for(j=i+1;j<=n;j++) ma[i][j]=ma[j][i]=inf; } for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); ma[a][b]=ma[b][a]=Min(ma[a][b],c);// // printf("%d\n",ma[a][b]); bian[i+1].u=a;bian[i+1].v=b; bian[i+1].w=c; } prime(); while(q--) { scanf("%d%d",&a,&b); // printf("%d\n",maxd[bian[a].u][bian[a].v]); if(maxd[bian[a].u][bian[a].v]>=b)//比较即可 printf("Yes\n"); else printf("No\n"); } } return 0; }
poj 2831 次小生成树模板
时间: 2024-10-09 17:57:16