当前位置: 首页 > 编程日记 > 正文

【Codeforces】Round #375 (Div. 2)

Position:http://codeforces.com/contest/723

我的情况

啊哈哈,这次raiting肯定要涨,接受过上次的教训,先用小号送肉,大号都是一发切,重回蓝咯

结果。。。

FST!!

不,这次是skip,A题gi了(从小号蒯来没改),其它就都会skip。。。。。。

大号被小号skip,大号还300多名(没WA),做不得卵声。结果小号rank408,+133raiting

恭喜LCFrank10,+279raiting

为了表示我被skip的愤怒,我决定用大号打Vitural

诶,有个人比我吊e,oo

反思

aaa下次用小号一定要改代码

C题没看懂导致A的时间很晚,少了400多分。EF没有时间,要提高时间,与代码的正确性。

全蓝了哦,算了,下次加油吧!頑張って!

官方题解

Round375


A. The New Year: Meeting Friends

time limit per test
1 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

There are three friend living on the straight line Ox in Lineland. The first friend lives at the point x1, the second friend lives at the point x2, and the third friend lives at the point x3. They plan to celebrate the New Year together, so they need to meet at one point. What is the minimum total distance they have to travel in order to meet at some point and celebrate the New Year?

It's guaranteed that the optimal answer is always integer.

Input

The first line of the input contains three distinct integers x1, x2 and x3(1 ≤ x1, x2, x3 ≤ 100) — the coordinates of the houses of the first, the second and the third friends respectively.

Output
Print one integer — the minimum total distance the friends need to travel in order to meet together.
input
7 1 4
output
6
input
30 20 10
output
20
Note

In the first sample, friends should meet at the point 4. Thus, the first friend has to travel the distance of 3 (from the point 7 to the point 4), the second friend also has to travel the distance of 3 (from the point 1 to the point 4), while the third friend should not go anywhere because he lives at the point 4.

Understanding

一个数轴上有三个人,他们要到一个地方聚会,使得每个人到这个地方的距离之和最小。

Solution

Greedy+Sort.我其实还没来得急看题,看了发样例,好像是最大数减最小数,赶快ma完交小号。。当时为了图快,随便搞,其实之后看了题还是可以证明的,如下:

R红色的为一种情况光是c→R,就>c-a(右边的算到a的距离)

B蓝色的一种情况,a→B+c→B=c-a,所以就只与B到b的距离有关

Y黄色,由B推来,当Y=b即为一个点答案为c-a,证毕

Code

// <A.cpp> - Mon Oct  3 19:17:39 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc. // I don't know what this program is.  #include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #pragma GCC push_options #pragma GCC optimize ("O2") #define MOD 1000000007 #define INF 1e9 #define IN inline #define RG register using namespace std; typedef long long LL; typedef long double LB; const int MAXN=100010; const int MAXM=100010; inline int max(int &x,int &y) {return x>y?x:y;} inline int min(int &x,int &y) {return x<y?x:y;} inline LL gi() { register LL w=0,q=0;register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')q=1,ch=getchar(); while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar(); return q?-w:w; } int main() { freopen("A.in","r",stdin); freopen("A.out","w",stdout); int a=gi(),b=gi(),c=gi(); printf("%d",max(max(abs(a-b),abs(b-c)),abs(a-c))); return 0; }

B. Text Document Analysis

time limit per test
1 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Modern text editors usually show some information regarding the document being edited. For example, the number of words, the number of pages, or the number of characters.

In this problem you should implement the similar functionality.

You are given a string which only consists of:

  • uppercase and lowercase English letters,
  • underscore symbols (they are used as separators),
  • parentheses (both opening and closing).

It is guaranteed that each opening parenthesis has a succeeding closing parenthesis. Similarly, each closing parentheses has a preceding opening parentheses matching it. For each pair of matching parentheses there are no other parenthesis between them. In other words, each parenthesis in the string belongs to a matching "opening-closing" pair, and such pairs can't be nested.

For example, the following string is valid: "_Hello_Vasya(and_Petya)__bye_(and_OK)".

Word is a maximal sequence of consecutive letters, i.e. such sequence that the first character to the left and the first character to the right of it is an underscore, a parenthesis, or it just does not exist. For example, the string above consists of seven words: "Hello", "Vasya", "and", "Petya", "bye", "and" and "OK". Write a program that finds:

  • the length of the longest word outside the parentheses (print 0, if there is no word outside the parentheses),
  • the number of words inside the parentheses (print 0, if there is no word inside the parentheses).
Input
The first line of the input contains a single integer n (1 ≤ n  ≤ 255) — the length of the given string. The second line contains the string consisting of only lowercase and uppercase English letters, parentheses and underscore symbols.
Output

Print two space-separated integers:

  • the length of the longest word outside the parentheses (print 0, if there is no word outside the parentheses),
  • the number of words inside the parentheses (print 0, if there is no word inside the parentheses).
input
37
_Hello_Vasya(and_Petya)__bye_(and_OK)
output
5 4
input
37
_a_(_b___c)__de_f(g_)__h__i(j_k_l)m__
output
2 6
Note
In the first sample, the words "Hello", "Vasya" and "bye" are outside any of the parentheses, and the words "and", "Petya", "and" and "OK" are inside. Note, that the word "and" is given twice and you should count it twice in the answer.

Understanding

给你一串字符,每个单词用_or()分开,问在括号外面的最长单词长度与括号里面单词个数。

Solution

细节题,Implementation

Code

// <B.cpp> - Mon Oct  3 19:17:39 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc. // I don't know what this program is.  #include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> using namespace std; const int MAXN=100010; const int MAXM=100010; inline int gi() { register int w=0,q=0;register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')q=1,ch=getchar(); while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar(); return q?-w:w; } char s[MAXN]; int main() { freopen("B.in","r",stdin); freopen("B.out","w",stdout); int n=gi(),ans=0,x=0;scanf("%s",s); for(int i=0;i<n;i++){ int j=i; while(s[j]!='('&&s[j]!='_'&&j<n)j++; if(j!=i)ans=max(j-i,ans); if(s[j]=='('){ for(j++;j<n;j++){ if(s[j]==')')break; int o=j; while(s[o]!='_'&&s[o]!=')'&&o<n)o++; if(o!=j)x++,j=o; if(s[o]==')')break; } } i=j; } printf("%d %d",ans,x); return 0; }

C. Polycarp at the Radio

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

Polycarp is a music editor at the radio station. He received a playlist for tomorrow, that can be represented as a sequence a1, a2, ..., an, where ai is a band, which performs the i-th song. Polycarp likes bands with the numbers from 1 to m, but he doesn't really like others.

We define as bj the number of songs the group j is going to perform tomorrow. Polycarp wants to change the playlist in such a way that the minimum among the numbersb1, b2, ..., bm will be as large as possible.

Find this maximum possible value of the minimum among the bj (1 ≤ j ≤ m), and the minimum number of changes in the playlist Polycarp needs to make to achieve it. One change in the playlist is a replacement of the performer of the i-th song with any other group.

Input

The first line of the input contains two integers n and m (1 ≤ m ≤ n ≤ 2000).

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109), where ai is the performer of the i-th song.

Output

In the first line print two integers: the maximum possible value of the minimum among the bj(1 ≤ j ≤ m), where bj is the number of songs in the changed playlist performed by the j-th band, and the minimum number of changes in the playlist Polycarp needs to make.

In the second line print the changed playlist.

If there are multiple answers, print any of them.

input
4 2
1 2 3 2
output
2 1
1 2 1 2
input
7 3
1 3 2 2 2 2 1
output
2 1
1 3 3 2 2 2 1

Understanding

给你一列数,要你将其修改。使得1~m的数目最小的最大,且修改数目最小。

My Solution

Greedy.首先要使1~m每个数出现次数最小的最多,平均分配一下,答案为n/m.然后要修改→将出现个数比n/m小的改为>=n/m.
第一遍,首先对于那些>m的数(不一定要改为<=m,开始WA了一发),如果有数(<=m)<n/m,将其改为那个数
第二遍,看有没有还有小于n/m的数,然后将出现个数>n/m的数改为这个数,直到个数为x
每一遍O(nm),总体O(nm)

Code

// <C.cpp> - Mon Oct  3 19:17:39 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc. // I don't know what this program is.  #include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #include <queue> using namespace std; typedef long long LL; const int MAXN=2010; inline LL gi() { register LL w=0,q=0;register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')q=1,ch=getchar(); while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar(); return q?-w:w; } int a[MAXN],f[MAXN],ans; int main() { freopen("C.in","r",stdin); freopen("C.out","w",stdout); int n=gi(),m=gi(),x=n/m; for(int i=1;i<=n;i++){a[i]=gi();if(a[i]<=m)f[a[i]]++;} printf("%d ",x); for(int i=1,j;i<=n;i++) if(a[i]>m) for(j=1;j<=m;j++) if(f[j]<x){ ans++;a[i]=j;f[j]++;break; } for(int i=1;i<=m;i++) if(f[i]<x) for(int j=1;j<=n;j++){ if(f[i]==x)break; if(f[a[j]]>x){ f[a[j]]--;f[i]++;ans++;a[j]=i; } } printf("%d\n",ans); for(int i=1;i<=n;i++)printf("%d ",a[i]); return 0; }

Zyt's Solution

Greedy.一次性处理,将>m的数丢到栈中。然后处理每一个1~m的数,优先放>m的数。

Code

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long #define inf 2147483640 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; const int maxn=2010; int a[maxn],b[maxn],n,m; int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]); int t=0; for (int i=1;i<=n;i++) { if (a[i]>m) t++; else b[a[i]]++; } int ans=n/m,cnt=0; for (int i=1;i<=m;i++) if (b[i]<ans) { if (t) { for (int j=1;j<=n;j++) { if (a[j]>m) a[j]=i,t--,b[i]++,cnt++; if (b[i]==ans) break; } if (b[i]==ans) continue; } for (int j=1;j<=n;j++) { if (b[a[j]]>ans) {b[a[j]]--;a[j]=i;b[i]++;cnt++;} if (b[i]==ans) break; } } printf("%d %d\n",ans,cnt); for (int i=1;i<=n;i++) printf("%d ",a[i]); return 0; }

D. Lakes in Berland

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

The map of Berland is a rectangle of the size n × m, which consists of cells of size 1 × 1. Each cell is either land or water. The map is surrounded by the ocean.

Lakes are the maximal regions of water cells, connected by sides, which are not connected with the ocean. Formally, lake is a set of water cells, such that it's possible to get from any cell of the set to any other without leaving the set and moving only to cells adjacent by the side, none of them is located on the border of the rectangle, and it's impossible to add one more water cell to the set such that it will be connected with any other cell.

You task is to fill up with the earth the minimum number of water cells so that there will be exactly k lakes in Berland. Note that the initial number of lakes on the map is not less than k.

Input

The first line of the input contains three integers n, m and k (1 ≤ n, m ≤ 50, 0 ≤ k ≤ 50) — the sizes of the map and the number of lakes which should be left on the map.

The next n lines contain m characters each — the description of the map. Each of the characters is either '.' (it means that the corresponding cell is water) or '*' (it means that the corresponding cell is land).

It is guaranteed that the map contain at least k lakes.

Output

In the first line print the minimum number of cells which should be transformed from water to land.

In the next n lines print m symbols — the map after the changes. The format must strictly follow the format of the map in the input data (there is no need to print the size of the map). If there are several answers, print any of them.

It is guaranteed that the answer exists on the given data.

input
5 4 1
****
*..*
****
**.*
..**
output
1
****
*..*
****
****
..**
input
3 3 0
***
*.*
***
output
1
***
***
***

Understanding

给你一个字符矩阵,'*'stand for sand,'.'stand for water

一个湖的定义为与边界没有交。求湖的个数<=k的最小填的个数,并且输出方案

Solution

广搜+贪心+sort.先处理边界海.然后将每个湖给抠出来,并记录大小,按大小排序,一个个湖删,因为发现填湖要全部填满,并且边界海也没用,贪心即可。

Code

// <D.cpp> - Mon Oct  3 19:17:39 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is.

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cstdlib>
#include <cmath>
using namespace std;
typedef long long LL;
const int MAXN=51;
inline LL gi() {register LL w=0,q=0;register char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')q=1,ch=getchar();while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();return q?-w:w;
}
bool f[MAXN][MAXN],u[MAXN][MAXN];
int _x[5]={0,0,-1,1},_y[5]={-1,1,0,0};
struct node{int x, y;};
struct bb{int s;vector<node>a;bool operator <(bb b)const{return s<b.s;}
}p[MAXN*MAXN];
queue<node>q;int n,m;
void work(int i,int j){q.push((node){i,j});u[i][j]=true;while(!q.empty()){int x=q.front().x,y=q.front().y;q.pop();for(int o=0,a,b;a=x+_x[o],b=y+_y[o],o<4;o++)if(!f[a][b]&&!u[a][b]&&a>=1&&a<=n&&b>=1&&b<=m)u[a][b]=1,q.push((node){a,b});}
}
int main()
{freopen("D.in","r",stdin);freopen("D.out","w",stdout);n=gi(),m=gi();int k=gi(),tot=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){char ch=getchar();while(ch!='.'&&ch!='*')ch=getchar();f[i][j]=bool(ch=='*');}}for(int i=1;i<=m;i++){if(!f[1][i]&&!u[1][i])work(1,i);if(!f[n][i]&&!u[n][i])work(n,i);}for(int i=1;i<=n;i++){if(!f[i][1]&&!u[i][1])work(i,1);if(!f[i][m]&&!u[i][m])work(i,m);}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(!f[i][j]&&!u[i][j]){q.push((node){i,j});p[++tot].s=1;u[i][j]=true;while(!q.empty()){int x=q.front().x,y=q.front().y;p[tot].a.push_back((node){x,y});q.pop();for(int o=0,a,b;a=x+_x[o],b=y+_y[o],o<4;o++)if(!f[a][b]&&!u[a][b]&&a>=1&&a<=n&&b>=1&&b<=m){u[a][b]=1;q.push((node){a,b});p[tot].s++;}}}sort(p+1,p+1+tot);int ans=0;k=tot-k;for(int i=1;i<=k;i++){for(int to=p[i].a.size(),j=0,x,y;x=p[i].a[j].x,y=p[i].a[j].y,j<to;j++)f[x][y]=1;ans+=p[i].s;}printf("%d\n",ans);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++)putchar(f[i][j]?'*':'.');cout<<endl;}return 0;
}

E. One-Way Reform

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

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.

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

Understanding

大意:将一个无向图改为有向图,求入度=出度的点最多个数,并输出方案。

Analysis

首先确定度数为奇数的点一定不能成为答案。所以答案<=n-奇点

再考虑这些初始度数为奇数的点,由于是无向图,这样的点的个数显然是偶数个的(无向图度数之和为偶数,偶点之和为偶数,奇点之和也要为偶数,奇数×偶数=偶数,奇数×奇数=奇数)

Solution

脑补图的知识-欧拉回路(下面有听不懂的地方请点这里的链接)

法一(my):

构造法,欧拉回路,Fleury

建一个虚点(n+1),把奇点向其连边,所有节点为偶点,可以构成欧拉回路,删掉之前加的边对,偶点不会发生改变,且入度=出度,所以答案为偶点个数,方案用Fleury找一遍欧拉回路即可。

法二(%小胖犇)

Greedy,每次从奇点出发找一条链(找到自己继续),除了终点(奇点),经过的点都走过偶数次(进去,出来),直到没有度数。

法三(flow-O(n*m))

建图:把所有点任意定向(奇点之间配对连边)

设w=abs(ind[i]-oud[i])/2

如果ind[i]>oud[i],就从i向ED连容量为w的边

如果oud[i]>ind[i],就从ST向i连容量为w的边

跑下最大流,如果满流,就存在欧拉回路

因为我们的连边方式,肯定满流,肯定存在在欧拉回路,我们只要通过流量判定边的具体方向就好了 

Code

// <E.cpp> - Mon Oct  3 19:17:39 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc. // I don't know what this program is.  #include<bits/stdc++.h> #pragma GCC push_options #pragma GCC optimize ("O2") #define IN inline #define RG register using namespace std; const int MAXN=210; inline int gi() { register int w=0,q=0;register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')q=1,ch=getchar(); while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar(); return q?-w:w; } set<int>s[MAXN]; vector<pair<int,int> >ans; IN void dfs(RG int x){ while(s[x].size()){ RG int p=*s[x].begin(); s[x].erase(p);s[p].erase(x); ans.push_back(make_pair(x,p));dfs(p); } } int main() { freopen("E.in","r",stdin); freopen("E.out","w",stdout); int T=gi(); while(T--){ ans.clear(); int n=gi(),m=gi(); while(m--){ int x=gi(),y=gi(); s[x].insert(y),s[y].insert(x); } for(int i=1;i<=n;i++) if(s[i].size()&1)s[n+1].insert(i),s[i].insert(n+1); printf("%d\n",n-s[n+1].size()); for(int i=1;i<=n;i++)dfs(i); for(int i=0,to=ans.size();i<to;i++) if(ans[i].first!=n+1&&ans[i].second!=n+1) printf("%d %d\n",ans[i].first,ans[i].second); } return 0; }

LCF's Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 201 #define maxm 40010 using namespace std; typedef long long llg; int T,n,m,sa[maxm],sb[maxm],ls,du[maxn],ans; bool g[maxn][maxn]; int getint(){ int w=0;bool q=0; char c=getchar(); while((c>'9'||c<'0')&&c!='-') c=getchar(); if(c=='-') c=getchar(),q=1; while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w; } void dfs(int u){ while(du[u]){ for(int i=1;i<=n;i++) if(g[u][i]){ ls++; sa[ls]=u; sb[ls]=i; du[u]--,du[i]--; g[u][i]=g[i][u]=0; u=i; break; } } } int main(){ //File("a"); T=getint(); while(T--){ ans=n=getint(); m=getint(); for(int i=1,x,y;i<=m;i++){ x=getint(); y=getint(); g[x][y]=g[y][x]=1; du[x]++; du[y]++; } for(int i=1;i<=n;i++) ans-=du[i]&1; printf("%d\n",ans); for(int i=1;i<=n;i++) if(du[i]&1) while(du[i]) dfs(i); for(int i=1;i<=n;i++) while(du[i]) dfs(i); for(int i=1;i<=ls;i++) printf("%d %d\n",sa[i],sb[i]); ls=0; } }

snowy_smile  の Code(flow)

#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;  #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|1  
typedef 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;  
}  

F. st-Spanning Tree

time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given an undirected connected graph consisting of n vertices and m edges. There are no loops and no multiple edges in the graph.

You are also given two distinct vertices s and t, and two values ds and dt. Your task is to build any spanning tree of the given graph (note that the graph is not weighted), such that the degree of the vertex s doesn't exceed ds, and the degree of the vertex t doesn't exceed dt, or determine, that there is no such spanning tree.

The spanning tree of the graph G is a subgraph which is a tree and contains all vertices of the graph G. In other words, it is a connected graph which contains n - 1 edges and can be obtained by removing some of the edges from G.

The degree of a vertex is the number of edges incident to this vertex.

Input

The first line of the input contains two integers n and m (2 ≤ n ≤ 200 000, 1 ≤ m ≤ min(400 000, n·(n - 1) / 2)) — the number of vertices and the number of edges in the graph.

The next m lines contain the descriptions of the graph's edges. Each of the lines contains two integers u and v (1 ≤ u, v ≤ n, u ≠ v) — the ends of the corresponding edge. It is guaranteed that the graph contains no loops and no multiple edges and that it is connected.

The last line contains four integers s, t, ds, dt (1 ≤ s, t ≤ n, s ≠ t, 1 ≤ ds, dt ≤ n - 1).

Output

If the answer doesn't exist print "No" (without quotes) in the only line of the output.

Otherwise, in the first line print "Yes" (without quotes). In the each of the next (n - 1) lines print two integers — the description of the edges of the spanning tree. Each of the edges of the spanning tree must be printed exactly once.

You can output edges in any order. You can output the ends of each edge in any order.

If there are several solutions, print any of them.

input
3 3
1 2
2 3
3 1
1 2 1 1
output
Yes
3 2
1 3

Understanding

给你一个图,求一个生成树,使得s的度数不超过ds,t的度数不超过dt,按输入顺序输出方案

Solution

Greedy+并查集.

先将不含s和t的其他点组成连通块。

然后接下来就是用s,t将构成树。

首先每个连通块只有3种情况:

  1. 与s或t相连,就只能连起,ds--||dt--
  2. 与s和t都相连,加入队列中之后处理
  3. 都不相连"No"

考虑将s与t连起,并且dsdt最大

如果有一个块与st相连,那么连起。否则,就看是不是已经连通,再否则就看s可不可以与t相连,再否则"No"

接下来因为s与t相连,其它的块就只需要找s||t连。

最后ds||dt <0 "No" else 输出结果。

Code

notice //this的地方

// <F.cpp> - Mon Oct  3 21:43:10 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is.

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define MOD 1000000007
#define INF 1e9
#define IN inline
#define RG register
using namespace std;
typedef long long LL;
typedef long double LB;
const int MAXN=200010;
const int MAXM=400010<<1;
inline int max(int &x,int &y) {return x>y?x:y;}
inline int min(int &x,int &y) {return x<y?x:y;}
inline LL gi() {register LL w=0,q=0;register char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')q=1,ch=getchar();while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();return q?-w:w;
}
int fr[MAXN],f[MAXN];int te;bool k[MAXM];
int to[MAXM],ne[MAXM],ev[MAXM],eu[MAXM],w[MAXM];vector<int>a[MAXN],b,c,d;
IN void link(int u,int v,int p){to[++te]=v;ne[te]=fr[u];fr[u]=te;w[te]=p;to[++te]=u;ne[te]=fr[v];fr[v]=te;w[te]=p;
}
IN int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
IN void pri(){printf("No");exit(0);}
int main()
{freopen("F.in","r",stdin);freopen("F.out","w",stdout);int n=gi(),m=gi();for(int i=1;i<=m;i++){eu[i]=gi();ev[i]=gi();link(eu[i],ev[i],i);}int s=gi(),t=gi(),ds=gi(),dt=gi();for(int i=1;i<=n;i++)f[i]=i;te=0;for(int i=1;i<=n;i++){if(i==s||i==t)continue;for(int o=fr[i];o;o=ne[o]){if(to[o]==s||to[o]==t)continue;f[i]=find(i);f[to[o]]=find(to[o]);if(f[i]!=f[to[o]])k[w[o]]=1,f[f[i]]=f[to[o]];}}for(int i=1;i<=n;i++){find(i);//this
        a[f[i]].push_back(i);}//this TLE→n^2for(int i=1;i<=n;i++){if(i==s||i==t||f[i]!=i)continue;int be1=0,be2=0;for(int j,kk=0,g=a[f[i]].size();j=a[f[i]][kk],kk<g;kk++)if(f[j]==i){for(int o=fr[j];o;o=ne[o])if(to[o]==s)be1=w[o];else if(to[o]==t)be2=w[o];if(be1&&be2)break;}if(!be1&&!be2)pri();//thisif(be1&&be2)b.push_back(be1),c.push_back(be2);else{if(be1)ds--,f[i]=s,k[be1]=1;if(be2)dt--,f[i]=t,k[be2]=1;}}    if(b.size())ds--,dt--,k[b[0]]=1,k[c[0]]=1;else {//thiste=find(1);for(int i=1;i<=n;i++)if(find(i)!=te){te=-1;break;}//thisif(te==-1){//thiste=0;for(int i=fr[s];i;i=ne[i])if(to[i]==t){te=1;k[w[i]]=1;break;}if(!te)pri();ds--;dt--;f[s]=t;}}for(int to=b.size(),i=1;i<to;i++){if(ds){ds--;k[b[i]]=1;continue;}dt--;k[c[i]]=1;}//thisif(ds<0||dt<0)pri();printf("Yes\n");for(int i=1;i<=m;i++)if(k[i])printf("%d %d\n",eu[i],ev[i]);//thisreturn 0;
}

转载于:https://www.cnblogs.com/YJinpeng/p/5931386.html

相关文章:

python的matplotlib背景线_python中matplotlib的颜色及线条 控制

https://www.cnblogs.com/darkknightzh/p/6117528.htmlhttps://blog.csdn.net/qq_34337272/article/details/795555441.设置栅格(1)使用pyplot api命令打开栅格:plt.grid(true)设置栅格格式&#xff1a;plt.grid(colorr, linestyle--, linewidth1,alpha0.3)(2)使用axes类面向对…

系统权限设计思路

权限系统通常包括如下基本元素&#xff1a;用户、角色、权限、资源、操作。 角色分类&#xff1a;总经理、部长、员工。&#xff08;在实际中一个用户可能存在多个角色&#xff0c;这就要考虑到权限累加处理&#xff09; 权限分类&#xff1a;如”员工考勤权限”、”审核权限”…

“区块链”究竟是什么

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 什么是区块链&#xff1f; 说到区块链&#xff0c;就不得不说比特币。 2008年底&#xff0c;比特币之父中本聪发表了一个关于他研究的电子现金…

leetcode 179. 最大数

给定一组非负整数&#xff0c;重新排列它们的顺序使之组成一个最大的整数。 示例 1: 输入: [10,2] 输出: 210 示例 2: 输入: [3,30,34,5,9] 输出: 9534330 说明: 输出结果可能非常大&#xff0c;所以你需要返回一个字符串而不是整数。 自己写了很久的比较函数&#xff0c;时钟有…

cf-Sasha and Array

题目链接 http://codeforces.com/problemset/problem/719/E 解题思路 矩阵上的线段树。 因为矩阵有分配律&#xff08;AB&#xff09;C AC BC&#xff0c;所以计算总和时直接把增量矩阵乘上去就行了。用矩阵快速幂。 fib的计算尽量拉到主函数计算。 代码 #include<stdio.h…

实对称矩阵的性质_浅谈矩阵的相似对角化(一)

森屿瑾年&#xff1a;浅谈线性变换和矩阵之间的关系​zhuanlan.zhihu.com通过前面的讨论&#xff0c;我们引出了线性变换在不同基下的矩阵之间的关系&#xff0c;知道了线性变换在不同基下的矩阵是相似的&#xff0c;进而我们可以通过选取不同的基&#xff0c;使得线性变换在这…

区块链技术未来可能用于哪些方面?

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 当世界上从100比特币购买25美分的比萨饼&#xff0c;到一比特币兑换4800人民币的天价&#xff0c;在这风起云涌的纪念&#xff0c;我们见证了一个…

tomcat启动

tomcat的启动一般是从startup.bat/startup.sh开始&#xff0c;然后启动catalina.bat/catalina.sh&#xff0c;然后启动bootstrap.jar包 那么它们启动的时候都做了哪些事情呢&#xff1f; 首先是startup.bat&#xff0c;startup.bat做了什么&#xff1f; 第二是catalina.bat&…

ERROR: from PIL import Image ImportError: No module named PIL

ERROR&#xff1a; from PIL import Image ImportError: No module named PIL 到 http://www.pythonware.com/products/pil/ 下载相关支持的版本 我的是python2.7 直接打开&#xff0c;然后一路按“下一步”&#xff0c;就行 转载于:https://www.cnblogs.com/jakejian/p/8992…

python中font_Python ColorFont包_程序模块 - PyPI - Python中文网

控制台打印彩色字体0 黑色 8 灰色1 蓝色 9 淡蓝色2 绿色 A 淡绿色3 浅绿色 B 淡浅绿色4 红色 C 淡红色5 紫色 D 淡紫色6 黄色 E 淡黄色7 白色 F 亮白色格式&#xff1a;0x12高位代表背景色&#xff0c;低位代表字体颜色0x10 | 0x020x10代表背景色&#xff0c;0…

区块链技术到底有啥用?

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 前言&#xff1a;关于区块链适合做什么和不适合做什么&#xff1f;一直都有争议。那么&#xff0c;通过什么方式来辨别呢&#xff1f;本文用详细的…

博客作业04--树

一.学习总结(2分) 1.1树结构思维导图 1.2 树结构学习体会 树的前中后序递归操作的访问路径都如下图 树的层次遍历的路径则如下图 操作{ 进队第一个节点&#xff0c; while(队不空&#xff09; { 访问该节点&#xff0c; if(BT->lchild&#xff01;NULL&#xff09;进队。 if…

oracle数据如何获取游标中动态字段_如何实现报表数据的动态层次钻取(二)

上一篇《如何实现报表数据的动态层次钻取&#xff08;一&#xff09;》介绍了利用复杂 sql 实现动态层次结构的方法&#xff0c;但该方法依赖 Oracle 的递归语法&#xff0c;在其他类型的数据库中难以实现。要想通用地实现此类报表&#xff0c;可以使用下面介绍的“集算脚本 本…

使用jsonp跨域请求后可以获得数据,但是进入error方法,返回parseerror

$.ajax({ url:url, dataType:jsonp, jsonp: callback,//回调函数名字 jsonpCallback: success_jsonpCallback,//可以不写&#xff0c;也可以自定义&#xff0c;用来取代 jQuery 自动生成的随机函数名&#xff0c;不写将由jq自动生成&#xff0c;每次生成的结果都不…

EOS技术学习笔记

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 EOS.IO软件引入了一种新的块链架构&#xff0c;旨在实现分布式应用的性能扩展。这是通过创建一个可以构建应用程序的类似操作系统的架构来实现的。…

PHP的一种缓存方案静态化

1,解决的问题。 2.如何实现。 面对大流量网站频繁访问数据库的一种优化&#xff0c;比如博客网站。不可能每个人查看都访问一次数据库。为了解决大量不必要访问的问题。 可以把第一次的内容保存为html页面。再以后定义的过期时间内都访问该静态页面。 以下是一个小的demo index…

python获取机器唯一标识_开发中常用工具 - 获取设备的唯一标识、UDID、UUID、keychain保存UUID、判断网络...

UDID全名&#xff1a;Unique Device Identifie(设备唯一标识符)说明&#xff1a;UDID&#xff0c;即设备唯一标识符&#xff0c;这是除序列号之外每台iOS设备的独一无二的号码。UDID只是和设备相关的&#xff0c;是用来区分每一个唯一的iOS设备(包括iPhone、iPad等)&#xff0c…

区块链安全入门笔记

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 虽然有着越来越多的人参与到区块链的行业之中&#xff0c;然而由于很多人之前并没有接触过区块链&#xff0c;也没有相关的安全知识&#xff0c;安…

PHP程序员的技术成长规划

PHP程序员的技术成长规划 作者&#xff1a;黑夜路人&#xff08;2014/10/15&#xff09; 按照了解的很多PHP/LNMP程序员的发展轨迹&#xff0c;结合个人经验体会&#xff0c;抽象出很多程序员对未来的迷漫&#xff0c;特别对技术学习的盲目和慌乱&#xff0c;简单梳理了这个每个…

【资源共享】RK3288 WiFiBT 开发配置参考说明

本文档主要介绍RK3288平台的WiFi&BT配置说明。 下载地址&#xff1a;http://dev.t-firefly.com/thread-13642-1-1.html更多开发资料请到社区精华系列“资源共享”专栏下载http://dev.t-firefly.com/forum-263-1.html转载于:https://www.cnblogs.com/TeeFirefly/p/9001757.h…

软件工程实训有必要吗_人工智能专业值得读吗?就业如何?

要说这几年的风口&#xff0c;人工智能首当其冲。热门是否代表了好就业&#xff1f;我觉得不是&#xff1b;那是不是就不好就业&#xff1f;我觉得也不是。先来看看这些耸人听闻的标题吧——“人工智能人才缺口超过500万&#xff0c;补齐人才短板乃是当务之急“人工智能就业前景…

区块链共识算法:PoS即权益证明 DPoS委托授权的权益证明

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 随着比特币价格暴涨&#xff0c;基于比特币的区块链技术引起各方关注&#xff0c;其核心就是共识算法。随着区块链技术的发展共识算法也在不断创新与…

【洛谷P1697】货车运输

首先&#xff0c;对于所有从x能到达y的路径中&#xff0c;限重越大越好 因此我们用Kruskal最大生成树得到一片森林&#xff08;不一定都联通&#xff09; 之后dfs维护森林的深度和LCA的预处理limit[x][0]&#xff08;x向上跳2^i步的边权最小值&#xff09; 对于每个询问&…

win7上Docker使用

1、启动docker&#xff1a; Docker Quickstart Terminal &#xff08;快捷键&#xff09;启动docker 2、SECURECRT工具链接docker&#xff1a; 转载于:https://www.cnblogs.com/aibaiyang/p/9007074.html

qt4的quick程序升级到qt5_最新8月书单出炉!送给你程序员

&#xff18;月好书赏不停&#xff0c;喜欢的就收藏一下。&#xff11;、计算广告&#xff1a;互联网商业变现的市场与技术&#xff08;第2版&#xff09;作者&#xff1a;刘鹏、王超全球第一本全面讲解计算广告与互联网变现秘密的专业图书升级版北冥乘海生 刘鹏老师力作&#…

都说区块链颠覆未来,区块链究竟能改变什么?

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 区块链&#xff0c;有时像个天使&#xff0c;有时像个魔鬼。 有人说它是金融泡沫&#xff0c;说他是彻底的庞氏骗局&#xff1b;有人说它能改变世界…

python银行家算法代码_避免死锁的银行家算法C++程序实现

&#xfeff;&#xfeff;本篇博文为追忆以前写过的算法系列第二篇(20081021)温故知新目的&#xff1a;具有代表性的死锁避免算法是Dijskstra给出的银行家算法。本实验是基于银行家算法的思想通过编写C程序实现银行家算法的计算机程序化。使其更有用。同一时候也加深了有关自愿…

shell脚本编程学习笔记(四)shell操作数据库

一、数据库基本操作 1&#xff09;登录mysql服务器&#xff1a;mysql -u root -p 密码 2&#xff09;查看数据库&#xff1a;show databases 3&#xff09;查看表&#xff1a;show tales from db; 4&#xff09;查看表结构&#xff1a;desc table; 5&#xff09;创建表&#xf…

WebFrom模拟MVC

如&#xff1a; aspx前台 这样写生成页面时不会产生新的html标签&#xff0c;用控件则会产生新的html标签 <h1><% title %></h1> <p><% content %></p><ul> <% foreach (string item in list){%> <li>…

区块链的未来在哪里

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 经历了早期的野蛮成长之后&#xff0c;区块链行业的发展开始回归理性客观的发展阶段。探索区块链对于互联网行业的支持作用&#xff0c;而非颠覆作…