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 }