题目传送门

题意:

  有n个人,m对关系,要求每对关系中,有且仅有一个人给另外一个人送礼物,并且使送出礼物最多的人送的礼物尽可能少。并输出送礼物的方案。

思路:这道题麻烦的是网络流模型的转换(废话)。

  最关键的因素是每对关系中只有一个人能给另外一个人送礼物,也就是说是不能相互送礼物的,虽然这句话是废话,但是正因为如此,如果我们考虑直接按照人建点,最后的方案会有问题。(流量相同,但方案错误)。

#pragma GCC optimize (2)
#pragma G++ optimize (2)
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
#include<cstdio>
#include<vector>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,b,a) for(int i=b;i>=a;i--)
#define clr(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pii pair<int,int >
using namespace std;
typedef long long ll;
const int maxn=;
const int inf=0x3f3f3f3f;
ll rd()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f; struct Edge {
int to, flow, nxt;
Edge() {}
Edge(int to, int nxt, int flow):to(to),nxt(nxt), flow(flow) {}
} edge[maxn << ]; int head[maxn], dep[maxn];
int S, T;
int N, n, m, tot,cnt;
vector<pair<int,int> >va;
void Init(int n) {
N = n;
for (int i = ; i <= N; ++i) head[i] = -;
tot = ;
} void addv(int u, int v, int w, int rw = ) {
edge[tot] = Edge(v, head[u], w);
head[u] = tot++;
edge[tot] = Edge(u, head[v], rw);
head[v] = tot++;
} bool BFS() {
for (int i = ; i <= N; ++i) dep[i] = -;
queue<int>q;
q.push(S);
dep[S] = ;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = head[u]; ~i; i = edge[i].nxt) {
if (edge[i].flow && dep[edge[i].to] == -) {
dep[edge[i].to] = dep[u] + ;
q.push(edge[i].to);
}
}
}
return dep[T] < ? : ;
} int DFS(int u, int f) {
if (u == T || f == ) return f;
int w, used = ;
for (int i = head[u]; ~i; i = edge[i].nxt) {
if (edge[i].flow && dep[edge[i].to] == dep[u] + ) {
w = DFS(edge[i].to, min(f - used, edge[i].flow));
edge[i].flow -= w;
edge[i ^ ].flow += w;
used += w;
if (used == f) return f;
}
}
if (!used) dep[u] = -;
return used;
} int Dicnic() {
int ans = ;
while (BFS()) {
ans += DFS(S, INF);
}
return ans;
}
int vs[][];
bool check(int res){
Init(T);
rep(i,,m){
addv(i+n,T,);
}
rep(i,,n){
addv(S,i,res);
}
rep(i,,m-){
int u=va[i].first,v=va[i].second;
addv(u,i++n,);
addv(v,i++n,);
}
int flow=Dicnic();
if(flow>=m){
return true;
}
return false;
} int main() {
while (~scanf("%d %d", &n, &m)) {
va.clear();
S = , T = n+m+;
rep(i,,m){
int u,v;
scanf("%d%d",&u,&v);
va.push_back({u,v});
}
int l=,r=n+,mid,ans=-;
while(l<=r){
mid=(l+r)>>;
if(check(mid)){
ans=mid;
r=mid-;
}else{
l=mid+;
}
} check(ans);
printf("%d\n", ans);
int flow=Dicnic();
for(int u=;u<=n;u++){
for(int i=head[u];i!=-;i=edge[i].nxt){ if(edge[i].flow==&&edge[i].to>n){
int id=edge[i].to-n;
int x= (va[id-].first==u?va[id-].second:va[id-].first);
printf("%d %d\n",u,x);
}
}
}
}
}

  所以我们要考虑建立n个点,每个点对应一个人,再建立m个点,每个点对应一对关系,每个关系向汇点连一条容量为1的边,每个人向自己所处的所有关系都连容量为1的边,这样就使得上面说的这个条件成立了。然后我们就建立虚拟源点,二分每个源点向人的流量,每次重新建图即可。

  最后输出方案,每个点流出的容量为0的边就是方案。

codeforces847J Students Initiation 网络流的更多相关文章

  1. 2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage

    2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage A. Union of Doubly Link ...

  2. Codeforces 最大流 费用流

    这套题目做完后,一定要反复的看! 代码经常出现的几个问题: 本机测试超时: 1.init函数忘记写. 2.addedge函数写成add函数. 3.边连错了. 代码TLE: 1.前向星边数组开小. 2. ...

  3. SGU 242. Student's Morning( 网络流 )

    看英文题真是麻烦...理解题意花的时间比想的时间还长...裸的网络流, 我们只要限制每个人出发流量为1, 每个大学进入的流量至多为2即可, 相当于构造可行解. -------------------- ...

  4. plain framework 1 网络流 缓存数据详解

    网络流是什么?为什么网络流中需要存在缓存数据?为什么PF中要采用缓存网络数据的机制?带着这几个疑问,让我们好好详细的了解一下在网络数据交互中我们容易忽视以及薄弱的一块.该部分为PF现有的网络流模型,但 ...

  5. 网络流模板 NetworkFlow

    身边的小伙伴们都在愉快地刷网络流,我也来写一发模板好了. Network Flow - Maximum Flow Time Limit : 1 sec, Memory Limit : 65536 KB ...

  6. COGS732. [网络流24题] 试题库

    «问题描述:假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法.«编程任务: ...

  7. ACM/ICPC 之 有流量上下界的网络流-Dinic(可做模板)(POJ2396)

    //有流量上下界的网络流 //Time:47Ms Memory:1788K #include<iostream> #include<cstring> #include<c ...

  8. BZOJ 3144 [Hnoi2013]切糕 ——网络流

    [题目分析] 网络流好题! 从割的方面来考虑问题往往会得到简化. 当割掉i,j,k时,必定附近的要割在k-D到k+D上. 所以只需要建两条inf的边来强制,如果割不掉强制范围内的时候,原来的边一定会换 ...

  9. bzoj3572又TM是网络流

    = =我承认我写网络流写疯了 = =我承认前面几篇博文都是扯淡,我写的是垃圾dinic(根本不叫dinic) = =我承认这道题我调了半天 = =我承认我这道题一开始是T的,后来换上真正的dinic才 ...

随机推荐

  1. 2019-9-2-win10-uwp-切换主题

    title author date CreateTime categories win10 uwp 切换主题 lindexi 2019-09-02 12:57:38 +0800 2018-2-13 1 ...

  2. 转 关于HTML5中meta name="viewport" 的用法 不同分辨率手机比例缩放

    移动端的布局不同于pc端,首先我们要知道在移动端中,css中的1px并不等于物理上的1px,因为手机屏幕的分辨率已经越来越高,高像素但是屏幕尺寸却没有发生太大变化,那就意味着一个物理像素点实际上塞入了 ...

  3. linux(一)vi和vim

    vi 多模式文本编辑器 多模式产生的原因 四种模式 正常模式 插入模式 命令模式 可视模式 vi man vi vim vim正常模式 直接vim回车,或vim空格文件名回车 i进入插入模式 I(sh ...

  4. linux文件查找工具——locate,find

    一文件查找介绍 文件的查找就是在文件系统上查找符合条件的文件. 文件查找的方式:locate, find非实时查找也就是基于数据库查找的locate,效率特别高. 实时查找:find 二locate ...

  5. Spring解决循环依赖

    1.Spring解决循环依赖 什么是循环依赖:比如A引用B,B引用C,C引用A,它们最终形成一个依赖环. 循环依赖有两种 1.构造器循环依赖 构造器注入导致的循环依赖,Spring是无法解决的,只能抛 ...

  6. spring在WEB中的应用。

    1:创建IOC容器.在WEB应用程序启动的时候就创建.利用到监听器. ServletContextListener类的contextInitialized方法中 package com.struts2 ...

  7. java html生成图片html2canvas,Canvas2Image

    <html> <div id="pic" style="margin-left: 500px;position:fixed;opacity:0;&quo ...

  8. <自动化测试>之<selenium API 查找元素操作底层方法>

    搜罗了一些查找元素的除标准语句外,另外的语句使用方法,摘自 开源中国 郝云鹏driver = webdriver.Chrome(); 打开测试页面 driver.get( "http://b ...

  9. JavaWeb解决中文乱码

    1.Get请求,方案有两种 A:修改Tomcat配置文件 server.xml   URIEncoding="UTF-8" 如:<Connector port="8 ...

  10. QTP学习笔记1

    1.将变量值写入datatable/ 从datatable中取值赋给变量 DataTable("列名","sheet名") = 变量名 变量名 = DataTa ...