BZOJ1576 (最短路+并查集)

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <queue>
  5 #define inline __attribute__((optimize("O2")))
  6 using namespace std;
  7    
  8 #define maxn 100008
  9 #define maxm 1000008
 10 #define INF 2000000000
 11 #define pa pair<int,int>
 12  
 13 struct line{
 14     int u,v,w,nt;
 15 }eg[maxm],E[maxm],e[maxm];
 16    
 17 int lt[maxn],fa[maxn],n,m,sum=1,num=0,f[maxn],ans[maxn];
 18 int d[maxn],pd[maxn];
 19    
 20 inline void add(int u,int v,int w){
 21     eg[++sum].v=v; eg[sum].w=w; eg[sum].nt=lt[u]; lt[u]=sum;
 22 }
 23 inline void read(int &x){
 24     char ch;
 25     for (ch=getchar();ch<'0'||ch>'9';ch=getchar()); x=ch-48;
 26     for (ch=getchar();ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-48;
 27 }
 28    
 29 /*inline void spfa(){
 30     for (int i=1;i<=n;i++) d[i]=INF;
 31     queue<int> Q;
 32     memset(pd,0,sizeof(pd));
 33     pd[1]=1; d[1]=0; Q.push(1);
 34     while (!Q.empty()){
 35         int u=Q.front();
 36         for (int i=lt[u];i;i=eg[i].nt){
 37             int v=eg[i].v;
 38             if (d[u]+eg[i].w<d[v]){
 39                 d[v]=d[u]+eg[i].w;
 40                 fa[v]=u;
 41                 if (!pd[v]){
 42                     Q.push(v);
 43                     pd[v]=1;
 44                 }
 45             }
 46         }
 47         pd[u]=0;
 48         Q.pop();
 49     }
 50 }*/
 51  
 52 inline void dijkstra(){
 53     priority_queue<pa,vector<pa>,greater<pa> > Q;
 54     memset(pd,0,sizeof(pd));
 55     for (int i=1;i<=n;i++) d[i]=INF;
 56     d[1]=0; Q.push(make_pair(0,1));
 57     while (!Q.empty()){
 58         int u=Q.top().second; Q.pop();
 59         if (pd[u]) continue; pd[u]=1;
 60         for (int i=lt[u];i;i=eg[i].nt)
 61             if (d[u]+eg[i].w<d[eg[i].v]){
 62                 d[eg[i].v]=d[u]+eg[i].w;
 63                 fa[eg[i].v]=u;
 64                 Q.push(make_pair(d[eg[i].v],eg[i].v));
 65             }
 66     }
 67 }
 68    
 69 inline bool cmp(line i,line j){
 70     return i.w<j.w;
 71 }
 72    
 73 inline int find(int x){ return f[x]==x?x:f[x]=find(f[x]); }
 74    
 75 inline void work(int u,int v,int w){
 76     int x=find(u),y=find(v);
 77     while (x!=y){
 78         if (d[x]<d[y]) swap(x,y);
 79         ans[x]=w-d[x];
 80         num++;
 81         f[x]=fa[x];
 82         x=find(f[x]);
 83     }
 84 }
 85    
 86 inline int main(){
 87     read(n); read(m);
 88     int x,y,z;
 89     for (int i=1;i<=m;i++){
 90         read(x); read(y); read(z);
 91         add(x,y,z); add(y,x,z);
 92         e[i].u=x; e[i].v=y; e[i].w=z;
 93     }
 94     dijkstra();
 95     int cnt=0;
 96     for (int i=1;i<=m;i++){
 97         int u=e[i].u,v=e[i].v,w=e[i].w;
 98         if (fa[u]!=v && fa[v]!=u){
 99             E[++cnt].u=u;
100             E[cnt].v=v;
101             E[cnt].w=d[u]+d[v]+w;
102         }
103     }
104     sort(E+1,E+cnt+1,cmp);
105     for (int i=1;i<=n;i++) { ans[i]=-1; f[i]=i; }
106     for (int i=1;i<=cnt;i++){
107         work(E[i].u,E[i].v,E[i].w);
108         if (num==n-1) break;      
109     }
110     for (int i=2;i<=n;i++) printf("%d\n",ans[i]);
111 }

 

posted @ 2015-06-24 14:35  rpSebastian  阅读(332)  评论(0编辑  收藏  举报