HDU 5889 Barricade(最短路+最小割)
http://acm.hdu.edu.cn/showproblem.php?pid=5889
题意:
给出一个图,帝国将军位于1处,敌军位于n处,敌军会选择最短路到达1点。现在帝国将军要在路径上放置障碍,每条边上都有一个放置障碍的代价。求至少需要多少代价。
思路:
首先就是求最短路,然后将最短路上的边重新进行构图跑最小割即可。
一开始求了两遍bfs,分别求出起点到各个点的距离和终点到各个点的距离,然后去判断每条边是否在最短路中,但是这样的话在最大流的构图中无法确定方向,然后就一直Wa。。。
其实跑一遍就够了。。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 #include<set> 11 #include<bitset> 12 using namespace std; 13 typedef long long ll; 14 typedef pair<int,int> pll; 15 const int INF = 0x3f3f3f3f; 16 const int maxn=1000+5; 17 18 int n,m; 19 20 vector<pll> G[maxn]; 21 bool vis[maxn]; 22 int d[maxn]; 23 24 void bfs(int s) 25 { 26 memset(vis,false,sizeof(vis)); 27 queue<int> Q; 28 Q.push(s); 29 d[s]=0; 30 vis[s]=true; 31 while(!Q.empty()) 32 { 33 int u=Q.front(); Q.pop(); 34 for(int i=0;i<G[u].size();i++) 35 { 36 int v=G[u][i].first; 37 if(!vis[v]) 38 { 39 vis[v]=true; 40 d[v]=d[u]+1; 41 Q.push(v); 42 } 43 } 44 } 45 } 46 47 struct Edge 48 { 49 int from,to,cap,flow; 50 Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){} 51 }; 52 53 struct Dinic 54 { 55 int n,m,s,t; 56 vector<Edge> edges; 57 vector<int> G[maxn]; 58 bool vis[maxn]; 59 int cur[maxn]; 60 int d[maxn]; 61 62 void init(int n) 63 { 64 this->n=n; 65 for(int i=0;i<n;++i) G[i].clear(); 66 edges.clear(); 67 } 68 69 void AddEdge(int from,int to,int cap) 70 { 71 edges.push_back( Edge(from,to,cap,0) ); 72 edges.push_back( Edge(to,from,0,0) ); 73 m=edges.size(); 74 G[from].push_back(m-2); 75 G[to].push_back(m-1); 76 } 77 78 bool BFS() 79 { 80 queue<int> Q; 81 memset(vis,0,sizeof(vis)); 82 vis[s]=true; 83 d[s]=0; 84 Q.push(s); 85 while(!Q.empty()) 86 { 87 int x=Q.front(); Q.pop(); 88 for(int i=0;i<G[x].size();++i) 89 { 90 Edge& e=edges[G[x][i]]; 91 if(!vis[e.to] && e.cap>e.flow) 92 { 93 vis[e.to]=true; 94 d[e.to]=d[x]+1; 95 Q.push(e.to); 96 } 97 } 98 } 99 return vis[t]; 100 } 101 102 int DFS(int x,int a) 103 { 104 if(x==t || a==0) return a; 105 int flow=0, f; 106 for(int &i=cur[x];i<G[x].size();++i) 107 { 108 Edge &e=edges[G[x][i]]; 109 if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0) 110 { 111 e.flow +=f; 112 edges[G[x][i]^1].flow -=f; 113 flow +=f; 114 a -=f; 115 if(a==0) break; 116 } 117 } 118 return flow; 119 } 120 121 int Maxflow(int s,int t) 122 { 123 this->s=s; this->t=t; 124 int flow=0; 125 while(BFS()) 126 { 127 memset(cur,0,sizeof(cur)); 128 flow +=DFS(s,INF); 129 } 130 return flow; 131 } 132 }DC; 133 134 int main() 135 { 136 //freopen("in.txt","r",stdin); 137 int T; 138 scanf("%d",&T); 139 while(T--) 140 { 141 scanf("%d%d",&n,&m); 142 for(int i=1;i<=n;i++) G[i].clear(); 143 for(int i=0;i<m;i++) 144 { 145 int u,v,w; 146 scanf("%d%d%d",&u,&v,&w); 147 G[u].push_back(make_pair(v,w)); 148 G[v].push_back(make_pair(u,w)); 149 } 150 bfs(1); 151 DC.init(n+1); 152 for(int i = 1;i<=n;i++) 153 for(int j = 0;j<G[i].size();j++) 154 if(d[G[i][j].first]==d[i]+1) 155 DC.AddEdge(i,G[i][j].first,G[i][j].second); 156 printf("%d\n",DC.Maxflow(1,n)); 157 } 158 return 0; 159 }