Gym - 101208C 2013 ACM-ICPC World Finals C.Surely You Congest 最大流+最短路
题意:给你n(2w5)个点,m条边(7w5)有k(1e3)辆车停在某些点上的,然后他们都想尽快去1号点,同时出发,同一个点不允许同时经过,
如果多辆车同时到达一个点,他们就会堵塞,这时候只能选择通过一辆车,其他车相当于就地爆炸
问最后能有多少车到1号点
题解:想象如果2辆车的最短路不相交,那么他们就互相之间没有了影响,再想象对于一般的图,如何控制度数的,显然有一个网络流的做法
可以走的边就连,度数为1,现在我们考虑每部分最短路长度相等的点集才会受到影响.如果2个点到1的最短路长度一样,那么他们才
可能会经过同一个点,于是针对每一堆最短路一样的,单独建图,累加他们的和就是答案.
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define lld long long 4 using namespace std; 5 #define N 30007 6 #define M 100007 7 #define inf 100000000000000LL 8 namespace Dinic 9 { 10 int head[N],head2[N],p=1; 11 struct Rec 12 { 13 int go,nex; 14 lld c; 15 }eg[M*2],e[M*2]; 16 void build(int a,int b,lld c) 17 { 18 //printf("%d %d %d\n",a,b,c); 19 eg[++p]=(Rec){b,head[a],-c}; 20 head[a]=p; 21 eg[++p]=(Rec){a,head[b],0}; 22 head[b]=p; 23 } 24 lld dis[N],ans; 25 int Q[N],s[N],S,T,stop; 26 bool bfs() 27 { 28 memset(dis,0,sizeof(dis)); 29 dis[T]=1; 30 Q[1]=T; 31 for (int p1=1,p2=1;p1<=p2;p1++) 32 { 33 for (int i=head[Q[p1]];i;i=eg[i].nex) 34 if (eg[i^1].c<0&&!dis[eg[i].go]) 35 { 36 dis[eg[i].go]=dis[Q[p1]]+1; 37 Q[++p2]=eg[i].go; 38 } 39 } 40 if (!dis[S]) return false; 41 memcpy(head2,head,sizeof(head)); 42 return true; 43 } 44 bool dinic(int p,int top) 45 { 46 if (p==T) 47 { 48 lld x=inf; 49 for (int i=1;i<=top-1;i++) if (-eg[s[i]].c<x) x=-eg[s[i]].c,stop=i; 50 for (int i=1;i<=top-1;i++) eg[s[i]].c+=x,eg[s[i]^1].c-=x; 51 ans+=x; 52 return true; 53 } 54 for (int &i=head2[p];i;i=eg[i].nex) 55 { 56 if (eg[i].c<0&&dis[eg[i].go]==dis[p]-1) 57 { 58 s[top]=i; 59 if (dinic(eg[i].go,top+1)&&top!=stop) return true; 60 } 61 } 62 return false; 63 } 64 lld ask() 65 { 66 ans=0; 67 while (bfs()) dinic(S,1); 68 return ans; 69 } 70 void init(int _S,int _T){ 71 S=_S,T=_T; 72 } 73 } 74 using namespace Dinic; 75 void clear() 76 { 77 p=1; 78 memset(head,0,sizeof(head)); 79 } 80 int n,m,ss,tt,why=0; 81 long long diss[N]; 82 void addedge(int a,int b,lld c) 83 { 84 p++; 85 e[p].go=b; 86 e[p].c=c; 87 e[p].nex=head[a]; 88 head[a]=p; 89 } 90 void dijkstra() 91 { 92 priority_queue<pa,vector<pa>,greater<pa> >q; 93 for (int i=1;i<=n;i++) diss[i]=inf; 94 diss[1]=0; 95 q.push(make_pair(0,1)); 96 while (!q.empty()) 97 { 98 int now=q.top().second; 99 q.pop(); 100 for (int i=head[now];i;i=e[i].nex) 101 if(diss[now]+e[i].c<diss[e[i].go]) 102 { 103 diss[e[i].go]=diss[now]+e[i].c; 104 q.push(make_pair(diss[e[i].go],e[i].go)); 105 } 106 } 107 } 108 int u[M],v[M],w[M],pos[M],c; 109 void solve(int l, int r) 110 { 111 clear(); 112 ss=n+1; 113 tt=n+2; 114 init(ss,tt); 115 for(int i = 1; i <= m; i++) build(u[i], v[i], 1); 116 for(int i = l; i <= r; i++) build(pos[i], tt, 1); 117 build(ss, 1, r - l + 1); 118 why += ask(); 119 //cout << ans <<endl; 120 } 121 bool cmp_(int a, int b) { 122 return diss[a] < diss[b]; 123 } 124 int main() 125 { 126 scanf("%d%d%d", &n, &m, &c); 127 p=0; 128 for(int i = 1; i <= m; i++) scanf("%d%d%d", &u[i], &v[i], &w[i]); 129 for(int i = 1; i <= c; i++) scanf("%d", &pos[i]); 130 for(int i = 1; i <= m; i++) addedge(u[i], v[i], w[i]), addedge(v[i], u[i], w[i]); 131 dijkstra(); 132 //for (int i=1;i<=n;i++) printf("%d\n",diss[i]); 133 int tmp = 0; 134 for(int i = 1; i <= m; i++) { 135 if(diss[u[i]] > diss[v[i]]) swap(u[i], v[i]); 136 if(diss[v[i]] == diss[u[i]] + w[i]) { 137 ++tmp; 138 swap(u[i], u[tmp]); 139 swap(v[i], v[tmp]); 140 swap(w[i], w[tmp]); 141 } 142 } 143 m = tmp; 144 sort(pos + 1, pos + c + 1, cmp_); 145 for(int i = 1, j; i <= c; i = j) { 146 j = i; 147 while(diss[pos[i]] == diss[pos[j]] && j <= c) j++; 148 if (diss[pos[i]]==inf) break; 149 solve(i, j - 1); 150 //cout << i << " " << j - 1 <<endl; 151 } 152 printf("%d", why); 153 return 0; 154 }
Anderyi!