zoukankan      html  css  js  c++  java
  • zoj 3135 Party of 8g 最大点权独立集

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3165

    题意:有M个男孩和N个女孩 他们每个人都有一个love值。

    现在要邀请他们中的一部分人,满足他们之间没有“8g”关系。

    给出M,N,S. S表示有S对boy和girl之间有“8g”关系。

    思路:

    最大点权独立集。

    原图基础上增加源s和汇t。

    s向每个boy连一条边,容量为这个人的love值。

    每个girl向t连一条边,容量为这个人的love值。

    然后每对"bg"关系boy向girl连一条边,容量为正无穷。

    求最小割。答案 = 权值总和 - 最小割

    再输出哪几个男孩和女孩被邀请了。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define maxn 205
      4 const int inf = 0x3f3f3f3f;
      5 struct Edge
      6 {
      7     int from, to, cap, flow;
      8     Edge(int f, int t, int c, int fl)
      9     {
     10         from = f; to = t; cap = c; flow = fl;
     11     }
     12 };
     13 vector <Edge> edges;
     14 vector <int> G[maxn];
     15 int vis[maxn], cur[maxn], d[maxn];
     16 int s, t, n, m;
     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 u = q.front(); q.pop();
     35         for(int i = 0 ; i < G[u].size(); i++)
     36         {
     37             Edge &e = edges[G[u][i]];
     38             if(!vis[e.to] && e.cap > e.flow)
     39             {
     40                 d[e.to] = d[u]+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[x] + 1 == d[e.to] && (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, M, S;
     77 int b[110], g[110];
     78 int main()
     79 {
     80     while(~scanf("%d%d%d", &M, &N, &S))
     81     {
     82         edges.clear();
     83         for(int i = 0; i <= N+M+1; i++) G[i].clear();
     84         s = 0; t = N+M+1;
     85         int temp;
     86         int sum = 0;
     87         memset(b, 0, sizeof(b));
     88         memset(g, 0, sizeof(g));
     89         for(int i = 1; i <= M; i++) //BOY
     90         {
     91             scanf("%d", &temp);
     92             sum += temp;
     93             AddEdge(s, i, temp);
     94         }
     95         for(int i = 1; i <= N; i++) //GIRL
     96         {
     97             scanf("%d", &temp);
     98             sum += temp;
     99             AddEdge(i+M, t, temp);
    100         }
    101         for(int i = 1; i <= S; i++)
    102         {
    103             int a, b; scanf("%d%d", &a, &b);
    104             AddEdge(a, b+M, inf);
    105         }
    106         int flow = Maxflow();
    107         sum -= flow;
    108         //cout<<sum<<endl;
    109         int cntb = 0, cntg = 0;
    110         for(int i = 0; i < m; i+=2)
    111         {
    112             if(edges[i].from == s)
    113             {
    114                 if(vis[edges[i].to])
    115                 {
    116                     b[edges[i].to] = 1;
    117                     cntb++;
    118                 }
    119                     
    120             }
    121             if(edges[i].to == t)
    122             {
    123                 if(!vis[edges[i].from])
    124                 {
    125                     g[edges[i].from-M] = 1;
    126                     cntg++;
    127                 }
    128             }
    129         }
    130         printf("%d %d %d
    ", sum, cntb, cntg);
    131         bool flag = true;
    132         for(int i = 1; i <= M; i++)
    133         {
    134             if(b[i])
    135             {
    136                 if(flag) printf("%d", i), flag = false;
    137                 else printf(" %d",i);
    138             }
    139         }
    140         printf("
    ");
    141         flag = true;
    142         for(int i = 1; i <= N; i++)
    143         {
    144             if(g[i])
    145             {
    146                 if(flag) printf("%d", i), flag = false;
    147                 else printf(" %d", i);
    148             }
    149         }
    150         printf("
    ");
    151     }
    152     return 0;
    153 }
  • 相关阅读:
    【洛谷5052】[COCI2017-2018#7] Go(区间DP)
    【洛谷6564】[POI2007] 堆积木KLO(树状数组优化DP)
    【洛谷6940】[ICPC2017 WF] Visual Python++(扫描线)
    【洛谷6939】[ICPC2017 WF] Tarot Sham Boast(PGF结论题)
    【洛谷4123】[CQOI2016] 不同的最小割(最小割树)
    初学最小割树
    【洛谷6122】[NEERC2016] Mole Tunnels(模拟费用流)
    【洛谷6936】[ICPC2017 WF] Scenery(思维)
    【洛谷2805】[NOI2009] 植物大战僵尸(最大权闭合子图)
    【洛谷1393】Mivik 的标题(容斥+border性质)
  • 原文地址:https://www.cnblogs.com/titicia/p/4704949.html
Copyright © 2011-2022 走看看