BZOJ 1576[Usaco2009 Jan]安全路经Travel

Solution:最短路树+并查集/树链剖分维护

  1 #include <cstdio>
  2 #include <queue>
  3 #include <algorithm>
  4 inline void swap(int &a,int &b)
  5 {
  6     register int tmp=b;
  7     b=a;a=tmp;
  8 }
  9 inline int read()
 10 {
 11     register int k=0,c=getchar(),f=1;
 12     while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
 13     while (c>='0'&&c<='9')k=k*10+c-'0',c=getchar();
 14     return k*f;
 15 }
 16 const int maxn=500000+100,inf=1<<30;
 17 struct edg{
 18     int x,too,del,nxt;
 19 }edge[maxn];
 20 struct qaq{
 21     int dis,pos;
 22 };
 23 struct mc{
 24     int a,b,len;
 25 }e[maxn];
 26 bool v[maxn],used[maxn];
 27 int vis[maxn];
 28 int n,m,tot,tot2,a,b,c,dist[maxn],last[maxn],h[maxn];
 29 int fq[maxn],eg[maxn],fa[maxn];
 30 std::priority_queue<qaq>q;
 31 bool operator<(qaq a,qaq b){return a.dis>b.dis;}
 32 inline void add(int a,int b,int c)
 33 {
 34     edge[++tot].nxt=last[a];
 35     last[a]=tot;
 36     edge[tot].too=b;
 37     edge[tot].x=a;
 38     edge[tot].del=c;
 39 }
 40 inline bool cmp(mc a,mc b)
 41 {
 42     return a.len<b.len;
 43 }
 44 int gf(int now)
 45 {
 46     return fa[now]==now?now:fa[now]=gf(fa[now]); 
 47 }
 48 inline void spfa()
 49 {
 50     for (register int i=1;i<=n;i++)dist[i]=inf;
 51     v[1]=1;dist[1]=0;q.push((qaq){0,1});
 52     while (!q.empty())
 53     {
 54         register int now=q.top().pos;q.pop();
 55         for (register int i=last[now];i;i=edge[i].nxt)
 56         {
 57             if (dist[edge[i].too]>edge[i].del+dist[now])
 58             {
 59                 dist[edge[i].too]=dist[now]+edge[i].del;
 60                 fq[edge[i].too]=now;
 61                 eg[edge[i].too]=i;
 62                 if (!v[edge[i].too])
 63                 {
 64                     v[edge[i].too]=1;
 65                     q.push((qaq){dist[edge[i].too],edge[i].too});
 66                 }
 67             }
 68         }
 69         v[now]=0;
 70     }
 71 }
 72 int main()
 73 {
 74     tot=1;
 75     n=read();m=read();
 76     for (register int i=1;i<=n;i++)fa[i]=i;
 77     for (register int i=1;i<=m;i++)a=read(),b=read(),c=read(),add(a,b,c),add(b,a,c);
 78     spfa();
 79     for (register int i=1;i<=n;i++)used[eg[i]]=used[eg[i]^1]=1;
 80     for (register int i=1;i<=tot;i++)
 81     if (!used[i])
 82     {
 83         e[++tot2].a=edge[i].x;e[tot2].b=edge[i].too;
 84         e[tot2].len=edge[i].del+dist[edge[i].x]+dist[edge[i].too];
 85     }
 86     std::sort(e+1,e+tot2+1,cmp);
 87     for(register int i=1;i<=tot2;i++)
 88     {
 89         register int a=e[i].a,b=e[i].b,f1=gf(a),f2=gf(b),lasta=0,lastb=0;
 90         while (f1!=f2)
 91         {
 92             if (dist[a]<dist[b])swap(a,b),swap(f1,f2),swap(lasta,lastb);
 93             if (!vis[a])
 94             {
 95                 vis[a]=i;
 96                 if (lasta)fa[lasta]=a;
 97             }else if (lasta)fa[lasta]=f1;
 98             lasta=f1;a=fq[lasta];f1=gf(a);
 99         }
100     }
101     for (register int i=2;i<=n;i++)
102     if (!vis[i])printf("-1\n");else printf("%d\n",e[vis[i]].len-dist[i]);
103 }
View Code

 

posted @ 2017-10-18 19:30  Michael_Zhuang  阅读(177)  评论(0编辑  收藏  举报