hdu3472 混合图判断欧拉通路

对于欧拉回路,先判断出度入度的差是否为偶数,然后最大流一次。

此题是判断有无欧拉通路,前提要判断图是否连通,然后欧拉通路的条件:要么出入度差没有奇数,或者只有2个点。

所以先统计差为奇数的个数,如果不为0或2,不可能。然后如果为2,表示可能使欧拉路,所以此时可以将这两个点相连,类似添加一条无向边。然后就是判断是否为欧拉回路了。

#include<stdio.h>
#include<string.h>
#include<queue>
#define maxn 50
#define INF 9999999
using namespace std;
struct node
{
    int to;
    int v;
    int flag;
    int next;
}edge[1000*1000];
char s[1002][25];
int vis[maxn],pre[maxn],index,in[maxn],out[maxn],n,sum,t,ff;
int pa[maxn];
int find(int x)
{
    if(pa[x]!=x)pa[x]=find(pa[x]);
    return pa[x];
}
void add(int x,int y,int z)
{
    edge[index].to=y;
    edge[index].v=z;
    edge[index].flag=index+1;
    edge[index].next=pre[x];
    pre[x]=index++;
    edge[index].to=x;
    edge[index].v=0;
    edge[index].flag=index-1;
    edge[index].next=pre[y];
    pre[y]=index++;
}
int dfs(int u,int low)
{
    int i;
    if(u==t)
        return low;
    for(i=pre[u];i!=-1;i=edge[i].next)
    {
        if(vis[edge[i].to]==vis[u]+1&&edge[i].v)
        {
            int a=dfs(edge[i].to,min(low,edge[i].v));
            if(!a)continue;
            edge[i].v-=a;
            edge[edge[i].flag].v+=a;
            return a;
        }
    }
    return 0;
}
int BFS()
{
    int i;
    queue<int>q;
    memset(vis,-1,sizeof(vis));
    vis[0]=0;
    q.push(0);
    while(!q.empty())
    {
        int t=q.front();
        q.pop();
        for(i=pre[t];i!=-1;i=edge[i].next)
        {
            if(vis[edge[i].to]<0&&edge[i].v)
            {
                vis[edge[i].to]=vis[t]+1;
                q.push(edge[i].to);
            }
        }
    }
    if(vis[t]>0)
        return 1;
    return 0;
}
void Dinic()
{
    int ans=0;
    while(BFS())
    {
        while(1)
        {
            int a=dfs(0,INF);
            if(!a)break;
            ans+=a;
        }
    }
    if(ans==sum)
       printf("Case %d: Well done!\n",++ff);
    else
        printf("Case %d: Poor boy!\n",++ff);
}
void slove(int fs)
{
    int i,st,se;//欧拉路奇数点的开始结束点
    st=se=-1;
    int count=0,flag=0;
    for(i=1;i<=‘z‘-‘a‘+1;i++)
    {
        if(in[i]||out[i])
        {
            if(find(i)!=find(fs))
            {
                flag=1;
                break;
            }
            else if((out[i]-in[i])%2!=0)
            {
                count++;
                if(st==-1)st=i;
                else se=i;
            }
        }
    }
    if(count!=0&&count!=2) flag=1;

    if(flag)
        printf("Case %d: Poor boy!\n",++ff);
    else
    {
        if(count==2)
        {
            add(st,se,1);
            out[st]++;
            in[se]++;
        }
        for(i=1;i<=‘z‘-‘a‘+1;i++)
        {
            if(out[i]>in[i])
            {
                add(0,i,(out[i]-in[i])/2);
                sum+=((out[i]-in[i])/2);
            }
            else if(in[i]>out[i])
            {
                add(i,t,(in[i]-out[i])/2);
            }
        }
        Dinic();
    }
}
int init()
{
    int i,fs;
    t=‘z‘-‘a‘+2;
    sum=0;
    index=1;
    for(i=0;i<=30;i++)pa[i]=i;
    memset(pre,-1,sizeof(pre));
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        int z;
        scanf("%s %d",s[i],&z);
        int l=strlen(s[i]);
        int x=s[i][0]-‘a‘+1;
        int y=s[i][l-1]-‘a‘+1;
        in[y]++,out[x]++,fs=x;
        int fx=find(x),fy=find(y);
        if(fx!=fy)pa[fx]=fy;
        if(z)
        {
            add(x,y,1);
        }
    }
    return fs;
}
int main()
{
    ff=0;
    int t,father;
    scanf("%d",&t);
    while(t--)
    {
        father=init();
        slove(father);
    }
}
时间: 2024-10-25 02:19:17

hdu3472 混合图判断欧拉通路的相关文章

POJ--1300--Door Man【判断欧拉通路】

链接:http://poj.org/problem?id=1300 题意:有n个房间,每个房间有若干个门和别的房间相连,管家从m房间开始走,要回到自己的住处(0),问是否有一条路可以走遍所有的门并且没有重复的路. 思路:判断是否存在欧拉通路,根据欧拉通路.欧拉回路的性质来做.有两种情况:一种是欧拉回路,所有房间的门的个数都是偶数个,并且此时初始房间不是0,此时存在要求的路径,如果初始是0则不行.另一种是欧拉通路,只有两个房间门是奇数个,剩下都是偶数个,并且这两个房间一个是0,一个是当前起点,并且

POJ训练计划_Colored Sticks(字典树+判断欧拉通路)

解题报告 http://blog.csdn.net/juncoder/article/details/38236333 题目传送门 题意: 问给定一堆的棒,两端有颜色,相同的颜色的棒可以头尾相接,能否连在一条直线. 思路: 把每一根棒两端看成两个点,之间连着线,判断这样的一个图中是否有欧拉通路 欧拉通路: 在联通无向图中,经过G的每一条边一次并且仅有一次的路径为欧拉通路. 求欧拉通路的充分条件:图为联通图,并且仅有两个奇度数的结点或无奇度结点. #include <queue> #includ

CodeForces - 508D Tanya and Password(欧拉通路)

Description While dad was at work, a little girl Tanya decided to play with dad's password to his secret database. Dad's password is a string consisting of n + 2 characters. She has written all the possible n three-letter continuous substrings of the

UVA 10129 Play on Words (欧拉通路)

题意: 输入N(N <= 100000)个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同(例如:acm,malform,mouse).每个单词最多包含 1000 个小写字母.输入中可以有重复的单词. 思路: 把一个字母的两端开成节点,单词看成有向边,若问题有借,当且仅当图中存在欧拉通路.所有只需要判断由单词而构建的图是否存在欧拉通路,由于是有向边,所以利用有向图欧拉通路的判定就可以了. 判定条件 (1):底图是连通图 (2):可以有两个奇点,其中

POJ 2337 Catenyms 欧拉通路

题目链接:点击打开链接 题意: 把输入的n个由小写字母构成的字符串连成字典序最小的一句话,使得所有字符串都恰好出现一次且相邻两个字符串相邻的字母相同 思路: 比如abcd,我们认为是这样一条边:a->d 所以我们在a->d间建一条边. 1.如:abcd, dfgh, 那么得到的边就是 a->d, d->h. 而题目的目标是每个字符串恰好用一次,即每条边恰好用一次.也就是找一条欧拉通路 2.我们只需要关心字符串的首尾2个字母,所以我们认为图里只有26个节点. 3.判断欧拉通路是否存在

[ACM] POJ 2513 Colored Sticks (Trie树,欧拉通路,并查集)

Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 29736   Accepted: 7843 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a st

FZU 2112 并查集、欧拉通路

原题:http://acm.fzu.edu.cn/problem.php?pid=2112 首先是,票上没有提到的点是不需要去的. 然后我们先考虑这个图有几个联通分量,我们可以用一个并查集来维护,假设有n个联通分量,我们就需要n-1条边把他们连起来. 最后对于每个联通分量来说,我们要使它能一次走完,就是要求他是否满足欧拉通路,也就是这个联通分量中至多有2个度为奇数的点,每多出2个度为奇数的点,就多需要一条边(因为单个连通分量的所有点的度数之和为偶数,所以不可能存在奇数个奇数度数的点). 1 #i

hdu 1116 Play on Words(欧拉通路)

Problem Description Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because there is no other way to open the doors, the puzzle is very important for us. There is a large

POJ 2337 Catenyms (有向图欧拉通路)

Catenyms Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9914   Accepted: 2588 Description A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For e