HDU 5889 Barricade(最短路+最小割)

Posted 谦谦君子,陌上其华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

以上是关于HDU 5889 Barricade(最短路+最小割)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 5889 Barricade最小割

Barricade---hdu5889(最短路+网络流)

HDU 5889 Barricade

HDU5889 Barricade(最短路)(网络流)

[HDOJ5889]Barricade(spfa,最大流)

HDU 5889 Barricade (bfs + 最小割)