• the meaning of problems
There are n cities, reference numeral 1-n
Now with minimum effort Dulu
No. 1 such that the path from city to city side length n number
(Note that only longer than the longest)
Blocking a road at the cost of road weights
• ideas
Before Dulu, from 1 to n, the minimum path is shortest course
Want a side path would hands and feet in the shortest way
N is from 1 to the shortest find out a shortest FIG form,
Then use the smallest cost is not such that the shortest FIG communication
We are seeking the shortest path graph minimum cut
Then how to build the most short circuit diagram of it?
Respectively, and n 1 is the source point again run Dijkstra, find the shortest path to each point 1 and n,
DIS provided $ [1] [i] is the shortest $ 1 to i, $ dis [n] [i] $ i-n, the shortest
$ 1-> u-> v-> n $ a $ 1-> n $ is a shortest i.e. $ dis [1] [u] + w [u-> v] + dis [n] [v] = dis [1 ] [n-] $
Then, u-> v is 1> n shortest side of the road, in FIG shortest added
(Despise someone because the code is too messy, so dijkstra and dinic package a bit ...)
• Code
(Unpackaged Edition)
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mem(a,b) memset(a,b,sizeof(a)) 4 #define ll long long 5 #define INF 0x3f3f3f3f3f3f3f3f 6 #define P pair<long long,int> 7 const int maxn=1e5+5; 8 int n,m; 9 struct Edge 10 { 11 int v; 12 ll w; 13 int next; 14 }de[maxn],fe[maxn],e[maxn]; 15 16 int head1[maxn],head2[maxn]; 17 int cnt1,cnt2; 18 void add(int u,int v,ll w) 19 { 20 de[++cnt1]={v,w,head1[u]}; 21 head1[u]=cnt1; 22 23 fe[++cnt2]={u,w,head2[v]}; 24 head2[v]=cnt2; 25 } 26 27 ll dis1[maxn],disn[maxn]; 28 bool vis1[maxn],visn[maxn]; 29 priority_queue<P,vector<P>,greater<P> >pq; 30 31 void dijkstra() 32 { 33 while(!pq.empty()) 34 pq.pop(); 35 for(int i=1;i<=n;i++) 36 dis1[i]=INF,vis1[i]=0; 37 dis1[1]=0; 38 pq.push(make_pair(0,1)); 39 while(!pq.empty()) 40 { 41 int u=pq.top().second; 42 pq.pop(); 43 if(!vis1[u]) 44 { 45 vis1[u]=1; 46 for(int i=head1[u];~i;i=de[i].next) 47 { 48 int v=de[i].v; 49 dis1[v]=min(dis1[v],dis1[u]+de[i].w); 50 pq.push(make_pair(dis1[v],v)); 51 } 52 } 53 } 54 55 while(!pq.empty()) 56 pq.pop(); 57 for(int i=1;i<=n;i++) 58 disn[i]=INF,visn[i]=0; 59 disn[n]=0; 60 61 pq.push(make_pair(0,n)); 62 while(!pq.empty()) 63 { 64 int u=pq.top().second; 65 pq.pop(); 66 if(!visn[u]) 67 { 68 visn[u]=1; 69 for(int i=head2[u];~i;i=fe[i].next) 70 { 71 int v=fe[i].v; 72 disn[v]=min(disn[v],disn[u]+fe[i].w); 73 pq.push(make_pair(disn[v],v)); 74 } 75 } 76 } 77 } 78 79 int head[maxn],cnt; 80 int cur[maxn],d[maxn]; 81 void addEdge(int u,int v,ll w) 82 { 83 e[++cnt]={v,w,head[u]}; 84 head[u]=cnt; 85 86 e[++cnt]={u,0,head[v]}; 87 head[v]=cnt; 88 } 89 90 bool bfs() 91 { 92 queue<int> q; 93 for(int i=1;i<=n;i++) 94 d[i]=-1; 95 d[1]=0; 96 q.push(1); 97 while(!q.empty()) 98 { 99 int u=q.front(); 100 q.pop(); 101 for(int i=head[u];~i;i=e[i].next) 102 { 103 int v=e[i].v; 104 if(d[v]==-1&&e[i].w>0) 105 { 106 d[v]=d[u]+1; 107 q.push(v); 108 } 109 } 110 } 111 return d[n]!=-1; 112 } 113 114 ll dfs(int u,ll flow) 115 { 116 ll nowflow=0; 117 if(u==n) return flow; 118 for(int i=cur[u];~i;i=e[i].next) 119 { 120 cur[u]=i; 121 int v=e[i].v; 122 if(d[v]==d[u]+1&&e[i].w>0) 123 { 124 ll k=dfs(v,min(flow-nowflow,e[i].w)); 125 if(k) 126 { 127 nowflow+=k; 128 e[i].w-=k; 129 e[i^1].w+=k; 130 if(nowflow==flow) 131 break; 132 } 133 } 134 } 135 if(!nowflow) d[u]=-2; 136 return nowflow; 137 } 138 139 ll Dinic() 140 { 141 ll ans=0; 142 while(bfs()) 143 { 144 for(int i=1;i<=n;i++) 145 cur[i]=head[i]; 146 147 ans+=dfs(1,INF); 148 } 149 return ans; 150 } 151 152 153 154 void Init() 155 { 156 mem(head1,-1); 157 mem(head2,-1); 158 mem(head,-1); 159 cnt1=cnt2=cnt=-1; 160 } 161 162 int main() 163 { 164 // freopen("C:\\Users\\14685\\Desktop\\C++workspace\\in&out\\contest","r",stdin); 165 int T; 166 scanf("%d",&T); 167 while(T--) 168 { 169 scanf("%d%d",&n,&m); 170 Init(); 171 for(int i=1;i<=m;i++) 172 { 173 int u,v; 174 ll w; 175 scanf("%d%d%lld",&u,&v,&w); 176 add(u,v,w); 177 } 178 179 dijkstra(); 180 181 for(int u=1;u<=n;u++) 182 { 183 for(int i=head1[u];~i;i=de[i].next) 184 { 185 int v=de[i].v; 186 if(dis1[u]+disn[v]+de[i].w==dis1[n]) 187 { 188 // printf("***%d %d %d\n",u,v,de[i].w); 189 addEdge(u,v,de[i].w); 190 } 191 } 192 } 193 194 printf("%lld\n",Dinic()); 195 } 196 }
(Packaged version)
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define pli pair<ll,int> 5 #define INF 0x3f3f3f3f3f3f3f3f 6 #define mem(a,b) memset(a,b,sizeof(a)) 7 const int maxn=1e5+5; 8 int n,m; 9 struct Edge 10 { 11 int v; 12 ll w; 13 int next; 14 }G[maxn<<1],e[maxn<<1]; 15 int dhead[maxn],dcnt; 16 void addEdge(int u,int v,ll w) 17 { 18 G[++dcnt]={v,w,dhead[u]}; 19 dhead[u]=dcnt; 20 } 21 22 struct Dij 23 { 24 ll dis[2][maxn]; 25 bool vis[maxn]; 26 priority_queue<pli,vector<pli>,greater<pli> > q; 27 void dij(int s,int n,bool ok) 28 { 29 for(int i=1;i<=n;i++) 30 dis[ok][i]=INF,vis[i]=0; 31 dis[ok][s]=0; 32 q.push({0,s}); 33 while(!q.empty()) 34 { 35 int u=q.top().second; 36 q.pop(); 37 if(vis[u]) 38 continue; 39 VIS [U] = . 1 ; 40 for ( int I = dhead [U]; ~ I; I = G [I] .next) 41 is { 42 is /// an even number is the forward side, ok = true is the forward edge 43 is IF ( I & && OK . 1 ) 44 is Continue ; 45 /// odd reverse side, ok = false reverse side 46 is IF (OK && (I &!! . 1 )) 47 Continue ; 48 49 int V = G [I]. V; 50 LL W = G [I] .W; 51 is IF (DIS [OK] [V]> DIS [OK] [U] +w) 52 { 53 dis[ok][v]=dis[ok][u]+w; 54 if(!vis[v]) 55 q.push({dis[ok][v],v}); 56 } 57 } 58 } 59 } 60 }dij1,dijn; 61 62 int head[maxn],cnt; 63 void add(int u,int v,ll w) 64 { 65 e[++cnt]={v,w,head[u]}; 66 head[u]=cnt; 67 } 68 struct Dinic 69 { 70 int cur[maxn],d[maxn]; 71 int s=1,t=n; 72 bool bfs() 73 { 74 queue<int> q; 75 for(int i=1;i<=n;i++) 76 d[i]=-1; 77 d[1]=0; 78 q.push(1); 79 while(!q.empty()) 80 { 81 int u=q.front(); 82 q.pop(); 83 for(int i=head[u];~i;i=e[i].next) 84 { 85 int v=e[i].v; 86 if(d[v]==-1&&e[i].w>0) 87 { 88 d[v]=d[u]+1; 89 q.push(v); 90 } 91 } 92 } 93 return d[n]!=-1; 94 } 95 96 ll dfs(int u,ll flow) 97 { 98 ll nowflow=0; 99 if(u==n) return flow; 100 for(int i=cur[u];~i;i=e[i].next) 101 { 102 cur[u]=i; 103 int v=e[i].v; 104 if(d[v]==d[u]+1&&e[i].w>0) 105 { 106 ll k=dfs(v,min(flow-nowflow,e[i].w)); 107 if(k) 108 { 109 nowflow+=k; 110 e[i].w-=k; 111 e[i^1].w+=k; 112 if(nowflow==flow) 113 break; 114 } 115 } 116 } 117 if(!nowflow) d[u]=-2; 118 return nowflow; 119 } 120 121 ll din() 122 { 123 ll ans=0; 124 while(bfs()) 125 { 126 for(int i=1;i<=n;i++) 127 cur[i]=head[i]; 128 129 ans+=dfs(1,INF); 130 } 131 return ans; 132 } 133 }_din; 134 135 void Init() 136 { 137 mem(dhead,-1); 138 dcnt=-1; 139 mem(head,-1); 140 cnt=-1; 141 } 142 143 int main() 144 { 145 int T; 146 scanf("%d",&T); 147 while(T--) 148 { 149 Init(); 150 Scanf ( " % D% D " , & n-, & m); 151 for ( int I = . 1 ; I <= m; I ++ ) 152 { 153 int U, V; 154 LL W; 155 Scanf ( " % D% D LLD% " , & U, V &, & W); 156 /// runs 1 to another point of the forward edge of the shortest Luke 157 addEdge (U, V, W); 158 /// run n shortest to other points is reverse side 159 addEdge (V, U, W); 160. } 161 162 dij1.dij (1,n,true); 163 dijn.dij(n,n,false); 164 165 166 for(int u=1;u<=n;u++) 167 { 168 for(int i=dhead[u];~i;i=G[i].next) 169 { 170 int v=G[i].v; 171 ll w=G[i].w; 172 if(dij1.dis[1][u]+dijn.dis[0][v]+w==dij1.dis[1][n]) 173 { 174 add(u,v,w); 175 add(v,u,0); 176 } 177 } 178 } 179 printf("%lld\n",_din.din()); 180 } 181 }