Problem E
KuPellaKes
In ancient times, many territories were under the control of a powerful king called Basm. Basm is well-known in history because of his strange works and as a result, there are many history-lovers who wish to know more about him. Koorosh is one of them and he has worked hard to find a way to know more about Basm’s works.
Recently, he managed to invent a Time Machine™ and traveled to the past to Basm time in order to be able to see and study his weird works thoroughly. Unfortunately, he has been caught by royal guard soldiers of Basm and is now in his prison. Basm ordered him to solve a problem if he wants to stay alive. King Basm wants to change the structure of roads of his newly captured territory, KuPellaKes in such a way that each city has an even number of neighboring cities. Now, he wants to know the minimum number of roads that should be destroyed in order to satisfy this condition. Note that each city must have at least one neighbor city after the road destruction process. Also, It should be noted that in the given territory at most two cites of KuPellaKes have an odd number of neighboring cities and there is at most one road between two cities. Also, there is no road from a city to itself.
The Input
Input consists of several test-cases. Each test-case starts with a line containing three numbers , m indicating the number of cities and roads in KuPellaKes respectively. Next m lines, each containing two numbers
indicating that there is a road between the
th and the
th city. Note that all the roads are bidirectional. Input will be terminated with a line containing three zeros.
The Output
For each test-case, your program should output the minimum number of roads that should be destroyed. In the case that this task is impossible the phrase “Poor Koorosh” should be printed.
Sample Input
4 5
1 2
2 3
3 4
4 1
1 3
0 0
Sample Output
1
Amirkabir University of Technology - Local Contest - Round #2
题意:给出一个无向图,图中最多只有两个度数为奇数的点,两个点之间最多只有一条边,也没有自环。你需要删掉尽量少的边,使得新图的任意点的度数都是大于0的偶数。
思路:我们想一想怎么样把一个奇数度数变成偶数度数呢?我们只需要删掉奇数条与这个点相连的边即可。但是当我们删掉后,可能又出现一个新的奇点。于是继续进行之前的操作。。。我们看到,这是一个奇点在沿着边移动。那怎么样把这个奇点消掉,那就要有另外一个奇点和这个奇点撞在一起,那么这个点就变成了偶点。。。于是我们只要求出原图中两个奇点的之间的最短路径即可。。。沿着这条最短路径,我们删掉所有的边,那么除了头和尾的度数-1以外,其他路径上的点的度数都-2,所以只有头尾的奇偶性改变了,其他都变。而且显然这也是最优的答案了。。。那么题目还有个限制条件就是删掉边之后不能有一个点的度数为0,这并不会给我们产生多大的困难,在求最短路的时候不要经过度数为2的点就好了。 另外什么情况下无解呢?1:两个奇点不可达(不经过度数为2的点的情况下)。2:一开始就已经有度数为0的点。 3:两个奇点至少有一个度数是1,因为删掉后,这个奇点就变成度数为0了。 最后如果一开始根本没有奇点,那么答案当然为0啦。
代码:
#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=1000+5;
const int inf=1e8;
int deg[maxn];
int d[maxn];
int n,m;
struct Node
{
int v;
Node*next;
}edges[maxn*maxn],*first[maxn];
int ptr;
void addEdge(int u,int v)
{
edges[++ptr].v=v;
edges[ptr].next=first[u];
first[u]=&edges[ptr];
}
void input()
{
memset(first,0,sizeof(first));
memset(deg,0,sizeof(deg));
ptr=0;
for(int i=0;i<m;++i)
{
int u,v;scanf("%d%d",&u,&v);
addEdge(u,v);
addEdge(v,u);
++deg[u],++deg[v];
}
}
int bfs(int s,int t)
{
queue<int> q;
for(int i=1;i<=n;++i) d[i]=inf;
q.push(s);
d[s]=0;
while(q.size())
{
int x=q.front(); q.pop();
for(Node *p=first[x];p!=NULL;p=p->next)
{
int v=p->v;
if(d[v]<=d[x]+1) continue;
if(deg[v]==2) continue;
d[v]=d[x]+1;
q.push(v);
}
}
return d[t];
}
void solve()
{
int zero=0,odd=0;
int s=-1,t=-1;
for(int i=1;i<=n;++i)
{
if(deg[i]==0) ++zero;
if(deg[i]&1)
{
++odd;
if(s==-1) s=i;
else t=i;
}
}
if(zero>=1) { printf("Poor Koorosh\n"); return; }
if(odd==0) { printf("0\n"); return; }
if(deg[s]==1||deg[t]==1) { puts("Poor Koorosh"); return; }
int ret=bfs(s,t);
if(ret==inf) puts("Poor Koorosh");
else printf("%d\n",ret);
}
int main()
{
while(scanf("%d%d",&n,&m)==2)
{
if(n+m==0) return 0;
input();
solve();
}
return 0;
}