携程的一道图论题
题意:给出一张无向图 每条边有一个长度和 删除该边的权值 再给出起点和终点 求从起点到终点的最短路增加 要删除的边的最小的权值和。
【思路】要使 从起点到终点的最短路长度增加 就要把该最短路破坏掉 从起点到终点的最短路可能不止一条,我们可以把 这些路径都找出来 重新构成一个图
再求这个图的最小割 就是答案了 怎么把这些路径都找出来呢 求两次最短路 第一次求 所有点到起点的最短路d1[x] 第二次求所有点到终点的最短 路 d2[x] 从起点到终点的最短路为ans 。再遍历每一条边 对于d1[u]+d2[v]+w[u][v]== ans 的边就可以加入了~
还要改一点 先放这里
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<cstdlib> 5 #include<queue> 6 #include<math.h> 7 #include<algorithm> 8 #include<vector> 9 #define maxx 9999999 10 using namespace std; 11 12 struct E{int from;int to;int c;int f;}; 13 struct node{int v;int w;int c;}; 14 vector <node> g1[1002]; 15 vector <int > g[1002]; 16 vector<E> edge; 17 int vis[1002],d1[1002],d2[1002],n,a[1002],p[1002],num[1002],cur[1002],d[1002]; 18 19 void add(int from,int to,int c) 20 { 21 E temp1,temp2; 22 temp1.from =from; temp1.to=to; temp1.c=c;temp1.f=0; 23 temp2.from =to; temp2.to=from; temp2.c=0;temp2.f=0; 24 edge.push_back (temp1); 25 edge.push_back (temp2); 26 int m=edge.size (); 27 g[from].push_back (m-2); 28 g[to].push_back (m-1); 29 } 30 31 void bfs(int s,int t) 32 { 33 int i; 34 queue<int > q; 35 q.push (t); 36 d[t]=0; 37 memset(vis,0,sizeof(vis)); 38 vis[t]=1; 39 while(!q.empty ()) 40 { 41 int t=q.front ();q.pop (); 42 for(i=0;i<g[t].size ();i++) 43 { 44 E e;e=edge[g[t][i]]; 45 if(!vis[e.to]) 46 { 47 q.push (e.to); 48 vis[e.to]=1; 49 d[e.to]=d[t]+1; 50 } 51 } 52 } 53 } 54 55 int zg(int s,int t) 56 { 57 int x=t,a=maxx; 58 while(x!=s) 59 { 60 //printf("x %d ",x); 61 E e=edge[p[x]]; 62 if(a>e.c-e.f) 63 a=e.c-e.f; 64 x=e.from; 65 } 66 x=t; 67 while(x!=s) 68 { 69 edge[p[x]].f+=a; 70 edge[p[x]^1].f-=a; 71 x=edge[p[x]].from ; 72 } 73 return a; 74 } 75 76 int maxflow(int s,int t,int n) 77 { 78 int flow=0,i; 79 bfs(s,t); 80 memset(num,0,sizeof(num)); 81 memset(cur,0,sizeof(cur)); 82 for(i=0;i<=t;i++) 83 num[d[i]]++; 84 int x=s; 85 while(d[s]<n) 86 { 87 if(x==t) 88 { 89 flow+=zg(s,t); 90 x=s; 91 printf("flow %d ",flow); 92 } 93 int ok=0; 94 for(i=cur[x];i<g[x].size ();i++) 95 { 96 E e; 97 e=edge[g[x][i]]; 98 if(e.c>e.f&&d[x]==d[e.to]+1) 99 { 100 ok=1; 101 102 p[e.to]=g[x][i]; 103 104 cur[x]=i; 105 x=e.to;//!@#$%^& 106 break; 107 } 108 } 109 if(ok==0) 110 { 111 int m=n; 112 for(i=0;i<g[x].size ();i++) 113 { 114 E e; 115 e=edge[g[x][i]]; 116 if(e.c>e.f&&m>d[e.to]) 117 m=d[e.to]; 118 } 119 if(--num[d[x]]==0) break; 120 num[d[x]=m+1]++; 121 cur[x]=0;////!@#$%^^& 122 if(x!=s) 123 x=edge[p[x]].from ; 124 125 } 126 } 127 return flow; 128 } 129 130 131 int spfa1(int s,int t) 132 { 133 queue<int > q; 134 memset(vis,0,sizeof(vis)); 135 for(int i=0;i<=n;i++) 136 d1[i]=maxx; 137 d1[s]=0; 138 vis[s]=1; 139 q.push(s); 140 while(!q.empty()) 141 { 142 int u; 143 u=q.front(); q.pop(); vis[u]=0; 144 for(int i=0;i<g1[u].size();i++) 145 { 146 int v; 147 v=g1[u][i].v; 148 if((d1[u]+g1[u][i].w)<d1[v]) 149 { 150 d1[v]=d1[u]+g1[u][i].w; 151 if(!vis[v]) 152 { 153 vis[v]=1; 154 q.push(v); 155 } 156 } 157 } 158 } 159 return d1[t]; 160 } 161 int spfa2(int s,int t) 162 { 163 queue<int > q; 164 memset(vis,0,sizeof(vis)); 165 for(int i=0;i<=n;i++) 166 d2[i]=maxx; 167 d2[s]=0; 168 vis[s]=1; 169 q.push(s); 170 while(!q.empty()) 171 { 172 int u; 173 u=q.front(); q.pop(); vis[u]=0; 174 for(int i=0;i<g1[u].size();i++) 175 { 176 int v; 177 v=g1[u][i].v; 178 if((d2[u]+g1[u][i].w)<d2[v]) 179 { 180 d2[v]=d2[u]+g1[u][i].w; 181 if(!vis[v]) 182 { 183 vis[v]=1; 184 q.push(v); 185 } 186 } 187 } 188 } 189 return d2[t]; 190 } 191 192 193 int main() 194 { 195 int m,i,j,a,b,s,t,t1,t2; 196 while(~scanf("%d%d",&n,&m)) 197 { 198 if(n==0&&m==0) 199 break; 200 scanf("%d%d",&s,&t); 201 for(i=0;i<=n;i++) 202 { 203 g[i].clear(); 204 g1[i].clear(); 205 } 206 edge.clear(); 207 while(m--) 208 { 209 scanf("%d%d%d%d",&a,&b,&t1,&t2); 210 node temp; 211 temp.v=b; temp.c=t2; temp.w=t1; 212 g1[a].push_back(temp); 213 temp.v=a; 214 g1[b].push_back(temp); 215 216 } 217 int ans; 218 ans=spfa1(s,t); 219 spfa2(t,s); 220 //printf("chang %d ",ans); 221 for(int i=1;i<=n;i++) //构图 求最大流 222 for(int j=0;j<g1[i].size();j++) 223 { 224 int v; 225 v=g1[i][j].v; 226 //printf("%d %d %d %d %d ",i,v,d1[i],d2[v],g[i][j].w); 227 if((d1[i]+d2[v]+g1[i][j].w)==ans||(d2[i]+d1[v]+g1[i][j].w)==ans)// 228 { 229 //printf("iv %d %d %d ",i,v,g1[i][j].c); 230 add(i,v,g1[i][j].c);//////// 231 } 232 } 233 //printf("***"); 234 //printf("st %d %d ",s,t); 235 printf("ans %d ",maxflow(s,t,n)); 236 } 237 return 0; 238 }