POJ 2831 次小生成树

来源:互联网 发布:来须苍真 知乎 编辑:程序博客网 时间:2024/05/21 13:57

题意:给你n个点,m个遍,q次询问。问你改了第i条边的权值,他能否使得最小价格降低,或不变。


想法:是次小生成树的变形,很简单,但是我被prime恶心死了。


#include<iostream>#include<cstring>#include<cstdio>#include<cassert>#define inf 0x7fffffffusing namespace std;const int nodes=1000+50;const int edges=1000000+500;int n,m,q;int map[nodes][nodes];struct node{int u,v;}e[edges];int vis[nodes],pre[nodes];int maxx[nodes][nodes];int Min(int a,int b){if(a<b) return a;return b;}void Input(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i==j) map[i][j]=0;else map[i][j]=inf;}}for(int i=1;i<=m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);e[i].u=a;e[i].v=b;map[a][b]=map[b][a]=Min(map[a][b],c);}} int Max(int a,int b){if(a>b) return a;return b;}void prime(){      int i,j,t,loc;      int dis[nodes];      memset(vis,0,sizeof(vis));      memset(maxx,0,sizeof(maxx));      for(i=1;i<=n;i++){         dis[i]=inf;      }      dis[1]=0;loc=1;vis[1]=1;      for(i=1;i<n;i++){         for(j=1;j<=n;j++){             if(!vis[j]&&map[loc][j]<dis[j]){                 dis[j]=map[loc][j],pre[j]=loc;             }         }        int min=inf;        for(j=1;j<=n;j++){            if(!vis[j]&&dis[j]<min) min=dis[loc=j];        }        for(j=1;j<=n;j++) if(vis[j]){            maxx[loc][j]=max(maxx[j][pre[loc]],dis[loc]);            maxx[j][loc]=maxx[loc][j];        }         vis[loc]=1;      }}void treatment(){while(q--){int a,b;scanf("%d%d",&a,&b);if(b<=maxx[e[a].u][e[a].v]) printf("Yes\n");else printf("No\n");}}int main(){while(~scanf("%d%d%d",&n,&m,&q)){Input();prime();treatment();}return 0;} 


注意:vis的更新。

#include<iostream>#include<cstring>#include<cstdio>#include<cassert>#define inf 0x7fffffffusing namespace std;const int nodes=1000+5;const int edges=1000000+500;int n,m,q;int map[nodes][nodes];struct node{int u,v;}e[edges];int maxx[nodes][nodes];int Min(int a,int b){if(a<b) return a;return b;}void Input(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i==j) map[i][j]=0;else map[i][j]=inf;}}for(int i=1;i<=m;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);e[i].u=a;e[i].v=b;map[a][b]=map[b][a]=Min(map[a][b],c);}} int Max(int a,int b){if(a>b) return a;return b;}void prime(){memset(maxx,0,sizeof(maxx));int pre[nodes],low[nodes],vis[nodes];for(int i=1;i<=n;i++){low[i]=map[1][i];pre[i]=1;vis[i]=0;}low[1]=0;vis[1]=1;pre[1]=-1;for(int i=2;i<=n;i++){int minn=inf;int pos;for(int j=1;j<=n;j++){if(!vis[j]&&minn>low[j]){minn=low[j];pos=j;}}vis[pos]=1;for(int j=1;j<=n;j++){if(vis[j]&&j!=pos){maxx[pos][j]=maxx[j][pos]=Max(maxx[j][pre[pos]],low[pos]);}if(!vis[j]&&low[j]>map[pos][j]){low[j]=map[pos][j];pre[j]=pos;}}}}void treatment(){while(q--){int a,b;scanf("%d%d",&a,&b);if(b<=maxx[e[a].u][e[a].v]) printf("Yes\n");else printf("No\n");}}int main(){while(~scanf("%d%d%d",&n,&m,&q)){Input();prime();treatment();}return 0;} 


1 0