您的位置:首页 > 运维架构

HDU 5348 MZL's endless loop 给边定向(欧拉回路,最大流)

2015-08-05 20:58 323 查看
题意:

  给一个所有你可能想得到的奇葩无向图,要求给每条边定向,使得每个点的入度与出度之差不超过1。输出1表示定向往右,输出0表示定向往左。

思路:

  网络流也是可以解决的!!应该挺简单理解的。但是由于复杂度的问题,EK和Dinic都搞不定,ISAP才行。

  利用欧拉回路的思想。既然每个点的入度与出度之差不超过1,那么在每两个奇数度的点添加1条无向边并不会影响到什么。那么先添加一些边进去,使得所有点的度都是偶数的。先随意帮每条边定个方向,进行建新图(用于跑最大流),假设u->v,那么u的出度就是可以给v的(当且仅当这条边反转时),建边u->v,容量为1。添加超级源点s连接到所有【出度大于入度的点】,容量为(出度-入度)/2,表示它有这么多个出度可以赠人。将所有【入度大于出度的点】连一条边到超级汇点t,容量为(入度-出度)/2,表示需要这么多的入度。接着跑一遍最大流(结果必定是满流的,即所有点的出度=入度),每条有流的边就需要将原来随意定下的方向反过来。参考

#include <bits/stdc++.h>
#define INF 0x7f7f7f7f
#define pii pair<int,int>
#define LL long long
using namespace std;
const int N=101000;

int main()
{
freopen("output.txt", "w+", stdout);
int t=100;//例子数
int a, b;
puts("100");
srand(time(0));
while(t--)
{
a=((int)rand())%100+1;//点数
b=((int)rand())%min((a*a),3000)+1;//边数
printf("\n\n%d %d\n\n", a, b);

for(int i=0; i<b; i++)
{
int u=((int)rand())%a+1;
int v=((int)rand())%a+1;
printf("%d %d\n",u,v);
}
}
return 0;
}


数据产生器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: