ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

圆桌问题

2021-05-29 19:04:07  阅读:183  来源: 互联网

标签:include int flow 问题 edges now 圆桌 dis


嘟嘟嘟

 

这道题建图还是很明白的:一个二分图,左边是单位,右边是餐桌,然后源点都向单位连一条容量为单位人数的边,每一个餐桌和汇点都连一条容量为餐桌容量的边(都叫容量~)。然后每一个单位向每一个餐桌都连一条容量为1的边,跑最大流即可。本来以为复杂度会很高,然而数据范围小,加上dinic玄学,很快就跑过了。

最后输出答案:如果最大流等于所有单位人数的话就说明满足要求,然后查询每一个单位的边的流量情况:如果这条边流满了,就说明该单位有一个人到了这一桌,那么输出该桌的编号。

后来知道这叫二分图多重匹配。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9 #include<stack>
 10 #include<queue>
 11 using namespace std;
 12 #define enter puts("") 
 13 #define space putchar(' ')
 14 #define Mem(a) memset(a, 0, sizeof(a))
 15 typedef long long ll;
 16 typedef double db;
 17 const int INF = 0x3f3f3f3f;
 18 const db eps = 1e-8;
 19 const int maxn = 455;
 20 inline ll read()
 21 {
 22     ll ans = 0;
 23     char ch = getchar(), last = ' ';
 24     while(!isdigit(ch)) {last = ch; ch = getchar();}
 25     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
 26     if(last == '-') ans = -ans;
 27     return ans;
 28 }
 29 inline void write(ll x)
 30 {
 31     if(x < 0) x = -x, putchar('-');
 32     if(x >= 10) write(x / 10);
 33     putchar(x % 10 + '0');
 34 }
 35 
 36 int m, n, t, Sum;
 37 struct Edge
 38 {
 39     int from, to, cap, flow;
 40 };
 41 vector<Edge> edges;
 42 vector<int> G[maxn];
 43 void addEdge(int from, int to, int w)
 44 {
 45     edges.push_back((Edge){from, to, w, 0});
 46     edges.push_back((Edge){to, from, 0, 0});
 47     int sz = edges.size();
 48     G[from].push_back(sz - 2);
 49     G[to].push_back(sz - 1);
 50 }
 51 
 52 int dis[maxn];
 53 bool bfs()
 54 {
 55     Mem(dis); dis[0] = 1;
 56     queue<int> q; q.push(0);
 57     while(!q.empty())
 58     {
 59         int now = q.front(); q.pop();
 60         for(int i = 0; i < (int)G[now].size(); ++i)
 61         {
 62             Edge& e = edges[G[now][i]];
 63             if(!dis[e.to] && e.cap > e.flow)
 64             {
 65                 dis[e.to] = dis[now] + 1;
 66                 q.push(e.to);
 67             }
 68         }
 69     }
 70     return dis[t];
 71 }
 72 int cur[maxn];
 73 int dfs(int now, int res)
 74 {
 75     if(now == t || res == 0) return res;
 76     int flow = 0, f;
 77     for(int& i = cur[now]; i < (int)G[now].size(); ++i)
 78     {
 79         Edge& e = edges[G[now][i]];
 80         if(dis[e.to] == dis[now] + 1 && (f = dfs(e.to, min(res, e.cap - e.flow))) > 0)
 81         {
 82             e.flow += f;
 83             edges[G[now][i] ^ 1].flow -= f;
 84             flow += f;
 85             res -= f;
 86             if(res == 0) break;
 87         }
 88     }
 89     return flow;
 90 }
 91 
 92 int maxflow()
 93 {
 94     int flow = 0;
 95     while(bfs())
 96     {
 97         Mem(cur);
 98         flow += dfs(0, INF);
 99     }
100     return flow;
101 }
102 
103 int main()
104 {
105     m = read(); n = read();
106     t = n + m + 1;
107     for(int i = 1; i <= m; ++i)
108     {
109         int x = read(); Sum += x;
110         addEdge(0, i, x);
111         for(int j = 1; j <= n; ++j) addEdge(i, j + m, 1);
112     }
113     for(int i = 1; i <= n; ++i) addEdge(i + m, t, read());
114     if(maxflow() == Sum) 
115     {
116         write(1); enter;
117         for(int i = 1; i <= m; ++i)
118         {
119             for(int j = 0; j < (int)G[i].size(); ++j)
120             {
121                 Edge e = edges[G[i][j]];
122                 if(e.to > m && e.cap - e.flow == 0)
123                     write(e.to - m), space;
124             }
125             enter;
126         }
127     }
128     else write(0), enter;
129     return 0;
130 }
View Code

 

标签:include,int,flow,问题,edges,now,圆桌,dis
来源: https://blog.51cto.com/u_15234622/2830921

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有