【Codeforces Round 375 (Div 2) E】【欧拉回路Fleury算法 或网络流】One-Way Reform 每条边定向使得最多的点满足入度=出度
来源:互联网 发布:js 打开新url 编辑:程序博客网 时间:2024/06/13 23:33
There are n cities and m two-way roads in Berland, each road connects two cities. It is known that there is no more than one road connecting each pair of cities, and there is no road which connects the city with itself. It is possible that there is no way to get from one city to some other city using only these roads.
The road minister decided to make a reform in Berland and to orient all roads in the country, i.e. to make each road one-way. The minister wants to maximize the number of cities, for which the number of roads that begins in the city equals to the number of roads that ends in it.
The first line contains a positive integer t (1 ≤ t ≤ 200) — the number of testsets in the input.
Each of the testsets is given in the following way. The first line contains two integers n and m (1 ≤ n ≤ 200, 0 ≤ m ≤ n·(n - 1) / 2) — the number of cities and the number of roads in Berland.
The next m lines contain the description of roads in Berland. Each line contains two integers u and v (1 ≤ u, v ≤ n) — the cities the corresponding road connects. It's guaranteed that there are no self-loops and multiple roads. It is possible that there is no way along roads between a pair of cities.
It is guaranteed that the total number of cities in all testset of input data doesn't exceed 200.
Pay attention that for hacks, you can only use tests consisting of one testset, so t should be equal to one.
For each testset print the maximum number of such cities that the number of roads that begins in the city, is equal to the number of roads that ends in it.
In the next m lines print oriented roads. First print the number of the city where the road begins and then the number of the city where the road ends. If there are several answers, print any of them. It is allowed to print roads in each test in arbitrary order. Each road should be printed exactly once.
25 52 14 52 31 33 57 23 74 2
31 33 55 43 22 132 43 7
#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<ctype.h>#include<math.h>#include<set>#include<map>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<time.h>using namespace std;void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(x))#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }const int N = 205, M = N * N * 20, Z = 1e9 + 7, inf = 0x3f3f3f3f;template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }int casenum, casei;int n, m;int ind[N], oud[N];int ST, ED;int first[N]; int id;int w[M], cap[M], nxt[M];void ins(int x, int y, int cap_){w[++id] = y;cap[id] = cap_;nxt[id] = first[x];first[x] = id;w[++id] = x;cap[id] = 0;nxt[id] = first[y];first[y] = id;}int d[N];bool bfs(){MS(d, -1);queue<int>q; q.push(ST); d[ST] = 0;while (!q.empty()){int x = q.front(); q.pop();for (int z = first[x]; z; z = nxt[z])if (cap[z]){int y = w[z];if (d[y] == -1){d[y] = d[x] + 1;q.push(y);if (y == ED)return 1;}}}return 0;}int dfs(int x, int all){if (x == ED)return all;int use = 0;for (int z = first[x]; z; z = nxt[z])if (cap[z]){int y = w[z];if (d[y] == d[x] + 1){int tmp = dfs(y, min(cap[z], all - use));cap[z] -= tmp;cap[z ^ 1] += tmp;use += tmp;if (use == all)break;}}if (use == 0)d[x] = -1;return use;}int dinic(){int ret = 0;while (bfs())ret += dfs(ST, inf);return ret;}int b[N], g;void solve(){int sum = 0;g = 0;for (int i = 1; i <= n; ++i){if (abs(ind[i] - oud[i]) % 2 == 1)b[++g] = i;}for (int i = 1; i <= g; i += 2){ins(b[i], b[i + 1], 1);++oud[b[i]];++ind[b[i + 1]];}for (int i = 1; i <= n; ++i){int w = abs(ind[i] - oud[i]) / 2;if (ind[i] > oud[i]){ins(i, ED, w);sum += w;}if (oud[i] > ind[i]){ins(ST, i, w);}}dinic();int ans = n - g;printf("%d\n", ans);for (int i = 2; i <= 2 * m; i += 2){if (cap[i] == 0)printf("%d %d\n", w[i], w[i ^ 1]);else printf("%d %d\n", w[i ^ 1], w[i]);}}int main(){scanf("%d", &casenum);for (casei = 1; casei <= casenum; ++casei){scanf("%d%d", &n, &m);ST = 0;ED = n + 1;MS(first, 0); id = 1;for (int i = 1; i <= n; ++i)oud[i] = ind[i] = 0;for (int i = 1; i <= m; ++i){int x, y; scanf("%d%d", &x, &y);++oud[x];++ind[y];ins(x, y, 1);}solve();}return 0;}/*【trick&&吐槽】【题意】n个点m条边的无向连通图没有自环没有重边我们要把所有点都定向希望使得尽可能多的点拥有相同的入度与出度让你输出满足这个条件的最大点数和每条边最后的定向【类型】欧拉回路 或 网络流【分析】首先,有一个猜想——就是满足那个条件的最大点数为拥有偶数度数的点数。基于这个猜想,我们可以把度数为奇数的点配对连边这时的图一定存在一个欧拉回路,也就使得每个点的入度=出度,使得我们的猜想成立我们可以用欧拉回路算法解决这道题,复杂度O(n+m)也可以套用网络流解决复杂度O(n*m)网络流的建图方式是——一开始把所有点任意定向,(奇点之间配对连边)后来把设w=abs(ind[i]-oud[i])/2如果ind[i]>oud[i],就从i向ED连容量为w的边如果oud[i]>ind[i],就从ST向i连容量为w的边这时跑下最大流,如果满流,就存在欧拉回路因为我们的连边方式,肯定满流,肯定从在欧拉回路我们只要通过流量判定边的具体方向就好了【时间复杂度&&优化】O(n+m) or O(nm)*/
- 【Codeforces Round 375 (Div 2) E】【欧拉回路Fleury算法 或网络流】One-Way Reform 每条边定向使得最多的点满足入度=出度
- Codeforces Round #375 (Div. 2) E. One-Way Reform(有n个点,m条无向边,给每条边定向,使得入度等于出度的点最多)
- codeforces #375(div.2) 723E One-Way Reform 欧拉回路或网络流
- Codeforces Round #375 (Div. 2) E - One-Way Reform (Fleury欧拉路径)
- [欧拉回路 构造 || 网络流] Codeforces 723E #375 (Div. 2) E. One-Way Reform
- Codeforces Round #375 (Div. 2) E. One-Way Reform 欧拉回路+构图
- Codeforces Round #375 (Div. 2) E One-Way Reform(欧拉路径,好题)
- Codeforces Round #375 (Div. 2) E. One-Way Reform 欧拉路径
- Codeforces Round #375 (Div. 2) E One-Way Reform(欧拉路径,好题)
- Codeforces Round #375 (Div. 2) -- E. One-Way Reform(dfs求欧拉回路)
- codeforces 723E. One-Way Reform(欧拉回路||网络流)
- Codeforces Round #375 (Div. 2)E. One-Way Reform
- Codeforces 723E One-Way Reform(欧拉回路)
- CodeForces 723E -One-Way Reform 构造+ 欧拉回路
- codeforces 723e One-Way Reform (欧拉回路) || 欧拉回路路径输出模板
- 欧拉回路 Codeforces723E One-Way Reform
- One-Way Reform(欧拉回路)
- Codeforce 723E - One-Way Reform(欧拉回路*,构造)
- C语言实现单层感知器
- 【Codeforces Round 375 (Div 2) D】【简单dfs】Lakes in Berland
- 用flask开发个人博客(20)—— 利用模型创建数据库
- opencv——cvPyrSegmentation
- 数据库主外键详解
- 【Codeforces Round 375 (Div 2) E】【欧拉回路Fleury算法 或网络流】One-Way Reform 每条边定向使得最多的点满足入度=出度
- Number Sequence
- UVA 10652 Board Wrapping 简单凸包
- 使用AsyncTask
- 快捷键
- 作业——素数的判断
- fedora下C++程序错误总结
- 初窥mysql
- [LeetCode 94]Binary Tree Inorder Traversal(迭代法)