zoukankan      html  css  js  c++  java
  • hdu 1054 Strategic Game 二分图最小点覆盖

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1054

    题意:

    给出一个无向图,求最小点覆盖。

    思路:

    用网络流来做设立一个超级源点和一个超级汇点。

    每个点拆成i和i'。

    从超级源点向点i连一条边,容量为1。

    从i’向超级汇点连一条边,容量为1。

    从i向i'连一条边,容量为正无穷。

    然后求最小割/2。因为拆点拆成了2个。

    也可以用二分图匹配来做,也是求出最大匹配然后/2。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 int n, m, s, t;
      4 #define maxn 3500
      5 #define inf 0x3f3f3f3f
      6 struct Edge
      7 {
      8     int from, to, cap, flow;
      9     Edge(int f, int t, int c, int fl)
     10     {
     11         from = f; to = t; cap = c; flow = fl;
     12     }
     13 };
     14 vector <Edge> edges;
     15 vector <int> G[maxn];
     16 int d[maxn], vis[maxn], cur[maxn];
     17 void AddEdge(int from, int to, int cap)
     18 {
     19     edges.push_back(Edge(from, to, cap, 0));
     20     edges.push_back(Edge(to, from, 0, 0));
     21     m = edges.size();
     22     G[from].push_back(m-2);
     23     G[to].push_back(m-1);
     24 }
     25 bool bfs()
     26 {
     27     memset(vis, 0, sizeof(vis));
     28     d[s] = 0;
     29     vis[s] = 1;
     30     queue <int> q;
     31     q.push(s);
     32     while(!q.empty())
     33     {
     34         int x = q.front(); q.pop();
     35         for(int i = 0; i < G[x].size(); i++)
     36         {
     37             Edge &e = edges[G[x][i]];
     38             if(!vis[e.to] && e.cap > e.flow)
     39             {
     40                 d[e.to] = d[x] + 1;
     41                 vis[e.to] = 1;
     42                 q.push(e.to);
     43             }
     44         }
     45     }
     46     return vis[t];
     47 }
     48 int dfs(int x, int a)
     49 {
     50     if(x == t || a == 0) return a;
     51     int flow = 0, f;
     52     for(int &i = cur[x]; i < G[x].size(); i++)
     53     {
     54         Edge &e = edges[G[x][i]];
     55         if(d[e.to] == d[x] + 1 && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0)
     56         {
     57             e.flow += f;
     58             edges[G[x][i]^1].flow -= f;
     59             flow += f;
     60             a -= f;
     61             if(a == 0) break;
     62         }
     63     }
     64     return flow;
     65 }
     66 int maxflow()
     67 {
     68     int flow = 0;
     69     while(bfs())
     70     {
     71         memset(cur, 0, sizeof(cur));
     72         flow += dfs(s, inf);
     73     }
     74     return flow;
     75 }
     76 int N;
     77 int main() 
     78 {
     79  //   freopen("in.txt", "r", stdin);
     80     //freopen("out.txt", "w", stdout);
     81     while(~scanf("%d", &N))
     82     {
     83         edges.clear();
     84         for(int i = 0; i <= 2*N+1; i++) G[i].clear();
     85         char op;
     86         int xh, cnt, u;
     87         s = 0; t = 2*N+1; n = 2*N+2;
     88         for(int i = 1; i <= N; i++) AddEdge(s, i, 1);
     89         for(int i = 1; i <= N; i++) AddEdge(i+N, t, 1);
     90         for(int i = 1; i <= N; i++)
     91         {
     92             scanf("%d", &xh); xh++;
     93             cin>>op; cin>>op;
     94             scanf("%d", &cnt);
     95             cin>>op;
     96             while(cnt--)
     97             {
     98                 scanf("%d", &u); u++;
     99                 AddEdge(xh, u+N, inf);
    100                 AddEdge(u, xh+N, inf);
    101             }
    102         }
    103         int flow = maxflow();
    104         printf("%d
    ", flow/2);
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    hdoj 2803 The MAX【简单规律题】
    hdoj 2579 Dating with girls(2)【三重数组标记去重】
    hdoj 1495 非常可乐【bfs隐式图】
    poj 1149 PIGS【最大流经典建图】
    poj 3281 Dining【拆点网络流】
    hdoj 3572 Task Schedule【建立超级源点超级汇点】
    hdoj 1532 Drainage Ditches【最大流模板题】
    poj 1459 Power Network【建立超级源点,超级汇点】
    hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】
    hdoj 1012 u Calculate e
  • 原文地址:https://www.cnblogs.com/titicia/p/5218602.html
Copyright © 2011-2022 走看看