Description

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.

Input

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.

Output

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.

Example
Input
2
5 5
2 1
4 5
2 3
1 3
3 5
7 2
3 7
4 2
Output
3
1 3
3 5
5 4
3 2
2 1
3
2 4
3 7

正解:构造+贪心

解题报告:

  这道题比赛的时候%王队的代码,结果王队写萎了一个地方,我不仅写萎了同一个地方,还自己弄出了一个新错误,直接FST。考虑我们希望使得s和t的度数尽可能小。那么显然,我们需要把不含s和t的边能连上的就连上,那么我们可以得到S、T和若干连通块。并且这些连通块之间没有边。我们考虑我们优先选择S、T和连通块相连,能连则连。

  其次我们考虑如果直接连接S和T,事实上是不划算的,因为如果把S和T分别和一个未被连入整体的连通块的话,同样减少一点度数,可以得到更优秀的答案(多连入了一个连通块)。所以我们接着考虑连接某个连通块,他与S、T都相连。需要注意:找到一个这样的连通块之后,我们只需要之后的对于这种连通块我们都只需要连上S或者T就可以了,显然选择度数比较多的那个会更优。最后我们再考虑S、T直接相连的情况。

  有很多细节,注意一下。

 //It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int inf = (<<);
const int MAXN = ;
const int MAXM = ;
int n,m,ecnt,s,t,ds,dt,root;
int ans[MAXM],cnt,father[MAXN];
bool use[MAXM];
int ok[MAXM][],jilu[MAXN][];
struct edge{
int x,y;
}e[MAXM];
inline int find(int x){ if(father[x]!=x) father[x]=find(father[x]); return father[x]; }
inline void rr(){ printf("No"); exit(); }
inline int getint()
{
int w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} inline void work(){
n=getint(); m=getint(); for(int i=;i<=m;i++) e[i].x=getint(),e[i].y=getint();
s=getint(); t=getint(); ds=getint(); dt=getint(); int r1,r2; for(int i=;i<=n;i++) father[i]=i;
for(int i=;i<=m;i++) {
if(e[i].x==s || e[i].y==s) continue; if(e[i].x==t || e[i].y==t) continue;
r1=find(e[i].x); r2=find(e[i].y);
if(r1!=r2) { father[r1]=r2; ans[++cnt]=i; use[i]=; }
}
bool flag=false;
for(int i=;i<=m;i++) {
if(use[i]) continue; if((e[i].x==s && e[i].y==t) || (e[i].x==t && e[i].y==s) ) { flag=true; root=i; continue; }
if(e[i].x==s) ok[find(e[i].y)][]=,jilu[find(e[i].y)][]=i;
if(e[i].y==s) ok[find(e[i].x)][]=,jilu[find(e[i].x)][]=i;
if(e[i].x==t) ok[find(e[i].y)][]=,jilu[find(e[i].y)][]=i;
if(e[i].y==t) ok[find(e[i].x)][]=,jilu[find(e[i].x)][]=i;
}
for(int i=;i<=n;i++) {
if(find(i)!=i) continue; if(i==s || i==t) continue;
if(ok[i][]+ok[i][]==) rr();
else if(ok[i][]+ok[i][]==) {
if(ok[i][]) ds--,ans[++cnt]=jilu[i][],use[jilu[i][]]=,r1=find(s),r2=find(i),father[r2]=r1;
else if(ok[i][]) dt--,ans[++cnt]=jilu[i][],use[jilu[i][]]=,r1=find(t),r2=find(i),father[r2]=r1;
}
}
if(ds< || dt<) rr();
for(int i=;i<=n;i++) {
if(find(i)!=i) continue; if(ok[i][]+ok[i][]<=) continue;
ds--; dt--; r1=find(s); r2=find(i); father[r2]=r1; r1=find(i); r2=find(t); father[r1]=r2;
ans[++cnt]=jilu[i][]; ans[++cnt]=jilu[i][];
use[jilu[i][]]=use[jilu[i][]]=;
break;
}
if(ds< || dt<) rr();
for(int i=;i<=n;i++) {
if(find(i)!=i) continue; if(ok[i][]+ok[i][]<=) continue;
if(find(i)==find(s)) continue;
if(ds>dt) ds--,ans[++cnt]=jilu[i][];
else dt--,ans[++cnt]=jilu[i][];
}
if(ds< || dt<) rr();
if(find(s)!=find(t)) {
if(flag) { ds--,dt--,ans[++cnt]=root; }
else rr();
}
if(ds< || dt<) rr();
printf("Yes\n");
for(int i=;i<=cnt;i++) printf("%d %d\n",e[ans[i]].x,e[ans[i]].y);
} int main()
{
work();
return ;
}

codeforces 723F : st-Spanning Tree的更多相关文章

  1. Codeforces Edu3 E. Minimum spanning tree for each edge

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  2. AtCoder Regular Contest 093 E: Bichrome Spanning Tree(生成树)

    Bichrome Spanning Tree 题意: 给出一个n个点,m条边的无向连通图,现在要给每条边染色,可以染成黑色或者白色. 现在要求在染色完毕后,找出一个至少包含一条黑边和一条白边的最小生成 ...

  3. 【19.27%】【codeforces 618D】Hamiltonian Spanning Tree

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. codeforces 342E :Xenia and Tree

    Description Xenia the programmer has a tree consisting of n nodes. We will consider the tree nodes i ...

  5. Codeforces 1682 D Circular Spanning Tree

    题意 1-n排列,构成一个圆:1-n每个点有个值0或者1,0代表点的度为偶数,1代表点的度为计数:询问能否构成一棵树,树的连边在圆内不会相交,在圆边上可以相交,可以则输出方案. 提示 1. 首先考虑什 ...

  6. Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA链上最大值

    E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...

  7. codeforces 609E Minimum spanning tree for each edge

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

  8. Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge 树上倍增

    E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...

  9. Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA/(树链剖分+数据结构) + MST

    E. Minimum spanning tree for each edge   Connected undirected weighted graph without self-loops and ...

随机推荐

  1. win7登录后开机密码破解读取

    在win7登录后,win7密码可以直接读取. https://github.com/gentilkiwi/mimikatz

  2. P1835 素数密度_NOI导刊2011提高(04)

    题目描述 给定区间[L,R](L≤R≤2147483647,R-L≤1000000),请计算区间中素数的个数. 输入输出格式 输入格式: 两个数L和R. 输出格式: 一行,区间中素数的个数. 输入输出 ...

  3. 035医疗项目-模块三:药品供应商目录模块——供货商药品目录(批量)添加药品的功能---------Service

    这篇文章我们重点介绍Service层.因为Dao层就是用Gysypml逆向生成的Mapper就可以了.所以这里重点讲解Service层. 业务逻辑如下: 1:我们从前端页面传入有两个值:1:userg ...

  4. 让Bootstrap轮播插件carousel支持左右滑动手势的三种方法

    因为最近开发的项目涉及到移动设备上的 HTML5 开发,其中需要实现轮播效果.然后最快捷的方式,你知道的(Bootstrap),然后原生的 Bootstrap 的 carousel.js 插件并没有支 ...

  5. SQL Server 百万级数据提高查询速度的方法

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉 ...

  6. Burndown chart

    S型的燃尽图 在一次milestone开发过程中,开发者会持续编辑issue列表,每个issue都有自己的生命周期.燃尽图预期这些issues会被线性的消灭掉,所以从第一天直接到最后一天画个直线表示预 ...

  7. Windbg调优Kafka.Client内存泄露

    从来没写过Blog,想想也是,工作十多年了,搞过N多的架构.技术,不与大家分享实在是可惜了.另外,从传统地ERP行业转到互联网,也遇到了很所前所未有的问题,原来知道有一些坑,但是不知道坑太多太深.借着 ...

  8. Qt学习笔记常用容器

    主要说Qt的以下几种容器 1.QList<T> 2.QLinkedList<T> 3.Map<T> 和一些常用的容器方法的使用 qSort qCopy qFind ...

  9. Theano2.1.13-基础知识之PyCUDA、CUDAMat、Gnumpy的兼容

    来自:http://deeplearning.net/software/theano/tutorial/gpu_data_convert.html PyCUDA/CUDAMat/Gnumpy comp ...

  10. 【前端也要学点算法】 归并排序的JavaScript实现

    前文我们了解了快速排序算法的实现,本文我们来了解下另一种流行的排序算法-归并排序算法. 我们先来回顾下快排.快排的核心是找出一个基准元素,把数组中比该元素小的放到左边数组,比该元素大的放到右边数组,如 ...