HDU 3046 Pleasant sheep and big wolf(最小割最大流+Dinic)

http://acm.hdu.edu.cn/showproblem.php?pid=3046

题意:

给出矩阵地图和羊和狼的位置,求至少需要建多少栅栏,使得狼不能到达羊。

 

思路:
狼和羊不能到达,最小割最大流问题。

因为狼和羊都有多只,所以我们加一个超级源点和一个超级汇点,将每只狼与超级源点相连,容量为INF,将每只羊与超级汇点相连,容量为INF。对于地图上的点,每个点都与它上下左右相连,容量设为1。

接下来,我们只需要计算出从超级源点到超级汇点的最大流,因为最小割等于最大流。

  1 #include<iostream> 
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<string>
  5 #include<vector>
  6 #include<queue>
  7 using namespace std;
  8 
  9 const int maxn = 210*210;
 10 const int INF = 0x3f3f3f3f;
 11 
 12 struct Edge
 13 {
 14     int from,to, cap, flow;
 15     Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){}
 16 };
 17 
 18 int n, m,t;
 19 vector<Edge> edges;
 20 vector<int> G[maxn];
 21 int vis[maxn];
 22 int d[maxn];   //从起点到i的距离
 23 int cur[maxn]; //当前弧下标
 24 int flow;
 25 
 26 void init()
 27 {
 28     for (int i = 0; i < maxn; i++)
 29         G[i].clear();
 30     edges.clear();
 31 }
 32 
 33 void AddEdge(int from, int to, int cap)
 34 {
 35     edges.push_back(Edge(from, to, cap, 0));
 36     edges.push_back(Edge(to, from, 0, 0));
 37     int m = edges.size();
 38     G[from].push_back(m - 2);
 39     G[to].push_back(m - 1);
 40 }
 41 
 42 
 43 int BFS()
 44 {
 45     memset(vis, 0, sizeof(vis));
 46     queue<int> Q;
 47     Q.push(0);
 48     d[0] = 0;
 49     vis[0] = 1;
 50     while (!Q.empty())
 51     {
 52         int x = Q.front();
 53         Q.pop();
 54         for (int i = 0; i < G[x].size(); i++)
 55         {
 56             Edge& e = edges[G[x][i]];
 57             if (!vis[e.to] && e.cap>e.flow)
 58             {
 59                 vis[e.to] = 1;
 60                 d[e.to] = d[x] + 1;
 61                 Q.push(e.to);
 62             }
 63         }
 64     }
 65     return vis[n*m + 1];
 66 }
 67 
 68 int DFS(int x,int a)
 69 {
 70     if (x == n*m + 1 || a == 0)  return a;
 71     int flow = 0, f;
 72     for (int& i = cur[x]; i < G[x].size(); i++)
 73     {
 74         Edge& e = edges[G[x][i]];
 75         if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow)))>0)
 76         {
 77             e.flow += f;
 78             edges[G[x][i] ^ 1].flow -= f;
 79             flow += f;
 80             a -= f;
 81             if (a == 0)  break;
 82         }
 83     }
 84     return flow;
 85 }
 86 
 87 void Maxflow(int s,int t)
 88 {
 89     flow = 0;
 90     while (BFS())
 91     {
 92         memset(cur, 0, sizeof(cur));
 93         flow += DFS(s, INF);
 94     }
 95 }
 96 
 97 int main()
 98 {
 99     //freopen("D:\\txt.txt", "r", stdin);
100     int kase = 0;
101     int a;
102     while (~scanf("%d%d", &n, &m))
103     {
104         init();
105         for (int i = 1; i <= n;i++)
106         for (int j = 1; j <= m; j++)
107         {
108             if (i != 1)
109                 AddEdge((i - 1)*m + j, (i-2)*m+j, 1);
110             if (i != n)
111                 AddEdge((i - 1)*m + j, i*m + j, 1);
112             if (j != 1)
113                 AddEdge((i - 1)*m + j, (i - 1)*m + j - 1, 1);
114             if (j != m)
115                 AddEdge((i - 1)*m + j, (i - 1)*m + j + 1, 1);
116             scanf("%d", &a);
117             if (a == 1)
118                 AddEdge(0, (i - 1)*m + j, INF);
119             else if (a == 2)
120                 AddEdge((i - 1)*m + j, m*n + 1, INF);
121         }
122         Maxflow(0, n*m + 1);
123         printf("Case %d:\n%d\n", ++kase, flow);
124     }
125 }

 

posted @ 2017-03-05 15:09  Kayden_Cheung  阅读(256)  评论(0编辑  收藏  举报
//目录