图论1E,cf405E
2016-03-19 10:20
309 查看
Little Chris is participating in a graph cutting contest. He's a pro. The time has come to test his skills to the fullest.
Chris is given a simple undirected connected graph with n vertices (numbered from 1 to n) and m edges.
The problem is to cut it into edge-distinct paths of length 2. Formally, Chris has to partition all edges of the graph into pairs in such a way that the edges in a single pair are adjacent and each edge must be contained in exactly one pair.
For example, the figure shows a way Chris can cut a graph. The first sample test contains the description of this graph.
You are given a chance to compete with Chris. Find a way to cut the given graph or determine that it is impossible!
Input
The first line of input contains two space-separated integers n and m (1 ≤ n, m ≤ 105),
the number of vertices and the number of edges in the graph. The next m lines contain the description of the graph's edges. The i-th
line contains two space-separated integers ai and bi (1 ≤ ai, bi ≤ n; ai ≠ bi),
the numbers of the vertices connected by the i-th edge. It is guaranteed that the given graph is simple (without self-loops and multi-edges) and connected.
Note: since the size of the input and output could be very large, don't use slow output techniques in your language. For example, do not use input and output streams (cin, cout) in C++.
Output
If it is possible to cut the given graph into edge-distinct paths of length 2, output
lines.
In the i-th line print three space-separated integersxi, yi and zi,
the description of the i-th path. The graph should contain this path, i.e., the graph should contain edges (xi, yi) and (yi, zi).
Each edge should appear in exactly one path of length 2. If there are multiple solutions, output any of them.
If it is impossible to cut the given graph, print "No solution" (without quotes).
Sample Input
Input
Output
Input
Output
Input
Output
1 2 3
题意:一个无向图,有你的顶点,m条边,输出m/2条边来,但是要包括所有顶点,输出规则 是,将两条边合并,这两条边有一个顶点是公用顶点,举一个例子:1-2 2-4 ,输出 1-2-4,;
借鉴大神的思路,先宽度搜索,然后深度优先搜索,一直到最低层,如果有落单顶点,那么将该顶点以及上一个顶点以及上上一个顶点输出,否者将上一个顶点加入队列:
这道题真的是不好想,最好看着代码将数据进行模拟一下,不然也是很难理解的
#include <iostream>
#include <queue>
#include <stdio.h>
#include <string.h>
const int maxn=1e6+10;
using namespace std;
struct Edge
{
int v,next;
}edge[maxn];
int head[maxn];
int tot;
bool vis[maxn];
void init()
{
tot=0;
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
}
void addedge(int u,int v)
{
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
}
int bfs(int u)
{
queue<int>que,que2;///队列2中连续存放的点,挨着的点都是相连的,队列2是主要队列
for(int i=head[u]; i!=-1; i=edge[i].next)
{
if(!vis[i])
{
int v=edge[i].v;
vis[i]=true;
vis[i^1]=true;
que.push(v);
}
}
while(!que.empty())
{
int mid=que.front();
que.pop();
int next=bfs(mid);
if(next)///如果有落单点输出落单点,上一点,上上一点
printf("%d %d %d\n",u,mid,next);
else
que2.push(mid);
}
while(que2.size()>=2)
{
int m1=que2.front();
que2.pop();
int m2=que2.front();
que2.pop();
printf("%d %d %d\n",m1,u,m2);
cout<<"####"<<endl;
}
if(!que2.empty())
return que2.front();///只返回,不删除队列中大于等于2个时,输出and删除
else
return 0;
}
int main()
{
int m,n,u,v;
while(scanf("%d%d",&n,&m)!=-1)
{
init();
for(int i=0; i<m; i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);///无向图,双向加边
addedge(v,u);
}
if(m%2==1)///计数个边肯定不行
{
printf("No solution\n");
}
else
bfs(1);
}
return 0;
}
Chris is given a simple undirected connected graph with n vertices (numbered from 1 to n) and m edges.
The problem is to cut it into edge-distinct paths of length 2. Formally, Chris has to partition all edges of the graph into pairs in such a way that the edges in a single pair are adjacent and each edge must be contained in exactly one pair.
For example, the figure shows a way Chris can cut a graph. The first sample test contains the description of this graph.
You are given a chance to compete with Chris. Find a way to cut the given graph or determine that it is impossible!
Input
The first line of input contains two space-separated integers n and m (1 ≤ n, m ≤ 105),
the number of vertices and the number of edges in the graph. The next m lines contain the description of the graph's edges. The i-th
line contains two space-separated integers ai and bi (1 ≤ ai, bi ≤ n; ai ≠ bi),
the numbers of the vertices connected by the i-th edge. It is guaranteed that the given graph is simple (without self-loops and multi-edges) and connected.
Note: since the size of the input and output could be very large, don't use slow output techniques in your language. For example, do not use input and output streams (cin, cout) in C++.
Output
If it is possible to cut the given graph into edge-distinct paths of length 2, output
lines.
In the i-th line print three space-separated integersxi, yi and zi,
the description of the i-th path. The graph should contain this path, i.e., the graph should contain edges (xi, yi) and (yi, zi).
Each edge should appear in exactly one path of length 2. If there are multiple solutions, output any of them.
If it is impossible to cut the given graph, print "No solution" (without quotes).
Sample Input
Input
8 12 1 2 2 3 3 4 4 1 1 3 2 4 3 5 3 6 5 6 6 7 6 8 7 8
Output
1 2 4 1 3 2 1 4 3 5 3 6 5 6 8 6 7 8
Input
3 3 1 2 2 3 3 1
Output
No solution
Input
3 2 1 2 2 3
Output
1 2 3
题意:一个无向图,有你的顶点,m条边,输出m/2条边来,但是要包括所有顶点,输出规则 是,将两条边合并,这两条边有一个顶点是公用顶点,举一个例子:1-2 2-4 ,输出 1-2-4,;
借鉴大神的思路,先宽度搜索,然后深度优先搜索,一直到最低层,如果有落单顶点,那么将该顶点以及上一个顶点以及上上一个顶点输出,否者将上一个顶点加入队列:
这道题真的是不好想,最好看着代码将数据进行模拟一下,不然也是很难理解的
#include <iostream>
#include <queue>
#include <stdio.h>
#include <string.h>
const int maxn=1e6+10;
using namespace std;
struct Edge
{
int v,next;
}edge[maxn];
int head[maxn];
int tot;
bool vis[maxn];
void init()
{
tot=0;
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
}
void addedge(int u,int v)
{
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
}
int bfs(int u)
{
queue<int>que,que2;///队列2中连续存放的点,挨着的点都是相连的,队列2是主要队列
for(int i=head[u]; i!=-1; i=edge[i].next)
{
if(!vis[i])
{
int v=edge[i].v;
vis[i]=true;
vis[i^1]=true;
que.push(v);
}
}
while(!que.empty())
{
int mid=que.front();
que.pop();
int next=bfs(mid);
if(next)///如果有落单点输出落单点,上一点,上上一点
printf("%d %d %d\n",u,mid,next);
else
que2.push(mid);
}
while(que2.size()>=2)
{
int m1=que2.front();
que2.pop();
int m2=que2.front();
que2.pop();
printf("%d %d %d\n",m1,u,m2);
cout<<"####"<<endl;
}
if(!que2.empty())
return que2.front();///只返回,不删除队列中大于等于2个时,输出and删除
else
return 0;
}
int main()
{
int m,n,u,v;
while(scanf("%d%d",&n,&m)!=-1)
{
init();
for(int i=0; i<m; i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);///无向图,双向加边
addedge(v,u);
}
if(m%2==1)///计数个边肯定不行
{
printf("No solution\n");
}
else
bfs(1);
}
return 0;
}
相关文章推荐
- 重写 strlen
- Linux中常用操作命令
- 数据分析入门
- iOS学习笔记—ViewController/生命周期
- WIN7右下角的声音图标不见了
- 关于VC中 error C2871: 'std' : does not exist or is not a namespace
- nyoj21 三个水杯 (BFS)
- 怎么给电脑统一设置查看文件为列表形式?
- Android开发之WebService介绍
- cocos2dx和quick的区别
- 关闭win7窗口自动排列功能的方法
- CAShapeLayer
- 2016年:如何测试您的网站响应时间
- 结对开发-四则运算3
- 结对开发——四则运算(三)
- dfs回溯的注意事项
- mt7688 音频方案分析
- 动态规划入门之国王的金矿
- Java中构造函数重构+数组小练习
- 索尼PS VR游戏体验汇总 399美元起高端VR究竟值不值得买?