• spoj 1693 Coconuts 最小割 二者取其一式


    题目链接:http://www.spoj.com/problems/COCONUTS/

    题意:N个城堡守卫就非洲的燕子能否搬运椰子而进行投票,每个人有自己的看法,但是为了避免跟自己的朋友持相反意见,他们时常会投相反的票。

    现在给出每个人的初始看法以及朋友关系,求在某种投票方案下,违背自己意愿与持不同意见的朋友对数的总和最小。

    思路:参考Edelweiss的《网络流建模汇总》。这是一个二者取其一式问题。

    设置超级源点S和T。

    每名守卫i如果赞成,连边s->i,容量为1;连边i->t,容量为0。

    如果反对,连边i->t,容量为1;连边s-i,容量为0。

    如果i和j是朋友,连边i->j和j->i,容量均为1。

    然后求最小割就可以了。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 int n, m, s, t;
      4 #define maxn 310
      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 cur[maxn], vis[maxn], d[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; vis[s] = 1;
     29     queue <int> q;
     30     q.push(s);
     31     while(!q.empty())
     32     {
     33         int x = q.front(); q.pop();
     34         for(int i = 0; i < G[x].size(); i++)
     35         {
     36             Edge &e = edges[G[x][i]];
     37             if(!vis[e.to] && e.cap > e.flow)
     38             {
     39                 d[e.to] = d[x]+1;
     40                 vis[e.to] = 1;
     41                 q.push(e.to);
     42             }
     43         }
     44     }
     45     return vis[t];
     46 }
     47 int dfs(int x, int a)
     48 {
     49     if(x == t || a == 0) return a;
     50     int flow = 0, f;
     51     for(int &i = cur[x]; i < G[x].size(); i++)
     52     {
     53         Edge &e = edges[G[x][i]];
     54         if(d[x]+1 == d[e.to] && (f = dfs(e.to, min(e.cap - e.flow, a))) > 0)
     55         {
     56             e.flow += f;
     57             edges[G[x][i]^1].flow -= f;
     58             flow += f;
     59             a -= f;
     60             if(a == 0) break;
     61         }
     62     }
     63     return flow;
     64 }
     65 int maxflow()
     66 {
     67     int flow = 0;
     68     while(bfs())
     69     {
     70         memset(cur, 0, sizeof(cur));
     71         flow += dfs(s, inf);
     72     }
     73     return flow;
     74 }
     75 int N, M;
     76 int main() 
     77 {
     78    // freopen("in.txt", "r", stdin);
     79   //  freopen("out.txt", "w", stdout);
     80     while(scanf("%d%d", &N, &M) && (N+M))
     81     {
     82         edges.clear();
     83         s = 0; t = N+1;
     84         for(int i = 0; i <= t; i++) G[i].clear();
     85         for(int i = 1; i <= N; i++)
     86         {
     87             int a; scanf("%d", &a);
     88             if(a)
     89             {
     90                 AddEdge(s, i, 1); AddEdge(i, t, 0);
     91             }
     92             else
     93             {
     94                 AddEdge(s, i, 0); AddEdge(i, t, 1);
     95             }
     96         }
     97         for(int i = 1; i <= M; i++)
     98         {
     99             int a, b; scanf("%d%d", &a, &b);
    100             AddEdge(a, b, 1); AddEdge(b, a, 1);
    101         }
    102         int flow = maxflow();
    103         printf("%d
    ", flow);
    104     }
    105     return 0;
    106 }
  • 相关阅读:
    String
    Xposed源码编译踩坑实录
    Hello 博客园
    HDU 1430 关系映射 + 打表 .
    HDU 1430 关系映射 + 打表 .
    hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数
    hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数
    hdu 1044 BFS(压缩图)+DFS
    hdu 1044 BFS(压缩图)+DFS
    hdu3338 最大流
  • 原文地址:https://www.cnblogs.com/titicia/p/5276841.html
Copyright © 2020-2023  润新知