Codeforces 330E Graph Reconstruction【随机化算法】Get it!
2017-07-31 14:37
459 查看
E. Graph Reconstruction
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
I have an undirected graph consisting of n nodes, numbered 1 through
n. Each node has at most two incident edges. For each pair of nodes, there is at most an edge connecting them. No edge connects a node to itself.
I would like to create a new graph in such a way that:
The new graph consists of the same number of nodes and edges as the old graph.
The properties in the first paragraph still hold.
For each two nodes u and
v, if there is an edge connecting them in the old graph, there is no edge connecting them in the new graph.
Help me construct the new graph, or tell me if it is impossible.
Input
The first line consists of two space-separated integers:
n and m (1 ≤ m ≤ n ≤ 105), denoting the number of nodes and edges, respectively. Then
m lines follow. Each of the
m lines consists of two space-separated integers
u and v (1 ≤ u, v ≤ n; u ≠ v), denoting an edge between nodes
u and v.
Output
If it is not possible to construct a new graph with the mentioned properties, output a single line consisting of -1. Otherwise, output exactly
m lines. Each line should contain a description of edge in the same way as used in the input format.
Examples
Input
Output
Input
Output
Input
Output
Note
The old graph of the first example:
A possible new graph for the first example:
In the second example, we cannot create any new graph.
The old graph of the third example:
A possible new graph for the third example:
题目大意:
给你一个图,有N个点,M条无向边,现在要求你建立出来一个新图,使得也是N个点M条无向边,并且需要保证每个点的度小于等于2(同时保证原图的度也小于等于2),并且要求旧图中有的边,新图中不能有。
如果一个点孤立出去了,相当于有一条边(u,u);
如果存在解,输出任意一个,否则输出-1.
思路:
初入门随机化算法,我们有N个点,最多N条边,那么我们随机这N个点的排列成一行,ans【i】和ans【i+1】建边,因为最多有N条边,所以我们再将ans【n】和ans【1】建边,构成一个环。
然后将其中的边进行判定,如果出现在原图了,这条边就不能建,否则就可以建,看看每一次随机出来的结果是否能够达到m条边,如果可以建立出m条边,就是一个可行的做法。
我们每一次随机完之后,如果有n个点,那么对于原图中假设存在有一个点a,其度为2.那么随机之后这个点能够连出一条边的概率是n-2/n。
所以随机化做法是完全可行的,一共有N*(N-1)/2条边,避免一个点接触到相邻两个点的概率是非常大的。
判重边用map标记一下就行。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
map<pair<int,int>,int>s;
int ans[100004];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
s.clear();
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
s[make_pair(x,y)]=1;
s[make_pair(y,x)]=1;
}
for(int i=1;i<=n;i++)
{
s[make_pair(i,i)]=1;
}
int flag=0;
for(int i=1;i<=n;i++)ans[i]=i;
int t=500;
while(t--)
{
random_shuffle(ans+1,ans+1+n);
ans[0]=ans
;
int cnt=0;
for(int i=0;i<n;i++)
{
if(s[make_pair(ans[i],ans[i+1])]==1)continue;
else cnt++;
}
if(cnt<m)continue;
flag=1;
for(int i=0;i<n;i++)
{
if(s[make_pair(ans[i],ans[i+1])]==1)continue;
if(m>0)
{
m--;
printf("%d %d\n",ans[i],ans[i+1]);
}
}
break;
}
if(flag==0)printf("-1\n");
}
}
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
I have an undirected graph consisting of n nodes, numbered 1 through
n. Each node has at most two incident edges. For each pair of nodes, there is at most an edge connecting them. No edge connects a node to itself.
I would like to create a new graph in such a way that:
The new graph consists of the same number of nodes and edges as the old graph.
The properties in the first paragraph still hold.
For each two nodes u and
v, if there is an edge connecting them in the old graph, there is no edge connecting them in the new graph.
Help me construct the new graph, or tell me if it is impossible.
Input
The first line consists of two space-separated integers:
n and m (1 ≤ m ≤ n ≤ 105), denoting the number of nodes and edges, respectively. Then
m lines follow. Each of the
m lines consists of two space-separated integers
u and v (1 ≤ u, v ≤ n; u ≠ v), denoting an edge between nodes
u and v.
Output
If it is not possible to construct a new graph with the mentioned properties, output a single line consisting of -1. Otherwise, output exactly
m lines. Each line should contain a description of edge in the same way as used in the input format.
Examples
Input
8 7 1 2 2 3 4 5 5 6 6 8 8 7 7 4
Output
1 4 4 6 1 6 2 7 7 5 8 5 2 8
Input
3 2 1 2 2 3
Output
-1
Input
5 4 1 2 2 3 3 4 4 1
Output
1 3 3 5 5 2 2 4
Note
The old graph of the first example:
A possible new graph for the first example:
In the second example, we cannot create any new graph.
The old graph of the third example:
A possible new graph for the third example:
题目大意:
给你一个图,有N个点,M条无向边,现在要求你建立出来一个新图,使得也是N个点M条无向边,并且需要保证每个点的度小于等于2(同时保证原图的度也小于等于2),并且要求旧图中有的边,新图中不能有。
如果一个点孤立出去了,相当于有一条边(u,u);
如果存在解,输出任意一个,否则输出-1.
思路:
初入门随机化算法,我们有N个点,最多N条边,那么我们随机这N个点的排列成一行,ans【i】和ans【i+1】建边,因为最多有N条边,所以我们再将ans【n】和ans【1】建边,构成一个环。
然后将其中的边进行判定,如果出现在原图了,这条边就不能建,否则就可以建,看看每一次随机出来的结果是否能够达到m条边,如果可以建立出m条边,就是一个可行的做法。
我们每一次随机完之后,如果有n个点,那么对于原图中假设存在有一个点a,其度为2.那么随机之后这个点能够连出一条边的概率是n-2/n。
所以随机化做法是完全可行的,一共有N*(N-1)/2条边,避免一个点接触到相邻两个点的概率是非常大的。
判重边用map标记一下就行。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
map<pair<int,int>,int>s;
int ans[100004];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
s.clear();
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
s[make_pair(x,y)]=1;
s[make_pair(y,x)]=1;
}
for(int i=1;i<=n;i++)
{
s[make_pair(i,i)]=1;
}
int flag=0;
for(int i=1;i<=n;i++)ans[i]=i;
int t=500;
while(t--)
{
random_shuffle(ans+1,ans+1+n);
ans[0]=ans
;
int cnt=0;
for(int i=0;i<n;i++)
{
if(s[make_pair(ans[i],ans[i+1])]==1)continue;
else cnt++;
}
if(cnt<m)continue;
flag=1;
for(int i=0;i<n;i++)
{
if(s[make_pair(ans[i],ans[i+1])]==1)continue;
if(m>0)
{
m--;
printf("%d %d\n",ans[i],ans[i+1]);
}
}
break;
}
if(flag==0)printf("-1\n");
}
}
相关文章推荐
- [Drupal] How to get the real path of a node, no matter it is a path or a url alias
- not just get it done
- IT忍者神龟之使用HttpURLConnection向服务器发送post和get请求
- How to write a first class paper and get it published in a scientific journal?
- boy, it's hard to get in the news
- Is it always safe to call getClass() within the subclass constructor?(转)
- error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
- Use C# to get JSON Data from the Web and Map it to .NET Class => Made Easy! 转
- The program 'rz' is currently not installed. You can install it by typing: apt-get install lrzsz
- pip install 时提示:error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Buil
- Are you looking for a way to get the entire text of a word document into a RichEdit without using the Clipboard?
- Get IT技能知识库 50个领域一键直达
- Get IT技能百科库 50个领域轻松直达
- [构造] Codeforces 717E Bubble Cup 9 - Finals E. Paint it really, really dark gray
- atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException
- CodeForces - 656F -Ace It!
- win10安装scrapy 报错 error: Microsoft Visual C++ 14.0 is required Get it with Microsoft V++ Comp……
- Atitit.java图片图像处理attilax总结 BufferedImage extends java.awt.Image获取图像像素点image.getRGB(i, lineIndex); 图片剪辑/AtiPlatf_cms/src/com/attilax/img/imgx.javacutImage图片处理titit 判断判断一张图片是否包含另一张小图片 atitit 图片去噪算法的原理与
- android studio编程时出现的错误:Cannot get property 'XXXX' on extra properties extension as it does not exis
- C/C++ launch a subprocess and get its output