现在的位置: 首页 > 综合 > 正文

HDOJ 3472 – HS BDC 判断混合图是否存在欧拉通路

2013年10月26日 ⁄ 综合 ⁄ 共 2701字 ⁄ 字号 评论关闭

               题意:

                       给一堆单词..有的单词是可以反过来的..两个单词能连接exactly前面单词的最后一个字母等于后面一个单词的第一个字母..问能否将所有单词连成一串....

               题解:

                       同样以字母为点,单词为边..把判断哈密顿通路转化成判断欧拉通路...

                       判断混合图是否存在欧拉通路: 无向边任意定向后,看有多少个点入度多了且度为奇数..有多少个点出度多了且度为奇数..若两个数量都为0..或者都为1并且加一条有向边连接两点(入度多了的指向出度多了的)..然后就和混合图欧拉回路一样的判断了...用最大流解决..话说此类问题一定不要忘记判断连通性!!!


Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<time.h>
#include<map>
#include<algorithm>
#define ll long long
#define eps 1e-5
#define oo 1000000007
#define pi acos(-1.0)
#define MAXN 50
#define MAXM 500005
using namespace std; 
int father[50];
bool used[50];
int getfather(int x)
{
      if (father[x]==x) return x;
      return father[x]=getfather(father[x]);
}
struct Dinic  
{  
      struct node   
      {  
             int x,y,c,next;  
      }line[MAXM];     
      int Lnum,_next[MAXN],dis[MAXN];  
      void initial(int n)   
      {  
             for (int i=0;i<=n;i++) _next[i]=-1;
             Lnum=-1;  
      }   
      void addline(int x,int y,int c)  
      {  
             line[++Lnum].next=_next[x],_next[x]=Lnum;  
             line[Lnum].x=x,line[Lnum].y=y,line[Lnum].c=c;  
             line[++Lnum].next=_next[y],_next[y]=Lnum;  
             line[Lnum].x=y,line[Lnum].y=x,line[Lnum].c=0;               
      }  
      bool BFS(int s,int e)  
      {   
             queue<int> Q;  
             while (!Q.empty()) Q.pop();  
             memset(dis,0,sizeof(dis));  
             dis[s]=1;  
             Q.push(s);  
             while (!Q.empty())  
             {  
                   int h,k;  
                   h=Q.front(),Q.pop();  
                   if (h==e) return dis[e];  
                   for (k=_next[h];k!=-1;k=line[k].next)  
                      if (line[k].c && !dis[line[k].y])  
                         dis[line[k].y]=dis[h]+1,Q.push(line[k].y);                   
             }   
             return false;  
      }  
      int dfs(int x,int flow,int e)    
      {       
             if (x==e) return flow;     
             int temp,cost=0;    
             for (int k=_next[x];k!=-1;k=line[k].next)    
             if (line[k].c && dis[line[k].y]==dis[x]+1)    
             {    
                    temp=dfs(line[k].y,min(flow-cost,line[k].c),e);     
                    if (temp)    
                    {    
                           line[k].c-=temp,line[k^1].c+=temp;    
                           cost+=temp;    
                           if (flow==cost) return cost;    
                    }else dis[line[k].y]=-1;    
             }    
             return cost;    
      }    
      int MaxFlow(int s,int e)  
      {  
             int MaxFlow=0;  
             while (BFS(s,e)) MaxFlow+=dfs(s,oo,e);   
             return MaxFlow;  
      }  
}T;   
bool judge(int s,int e,int id,int *d,int n)
{
       if (n==1) return true;
       int i; 
       if (n==1) return true;
       for (i=0;i<26;i++)
         if (used[i] && getfather(i)!=id) return false;
       int sum=0,t1=-1,t2=-1;
       for (i=0;i<26;i++)
          if (d[i]<0) 
          {
                 if (d[i]%2) 
                 {
                       if (t1!=-1) return false;
                       t1=i,d[i]++;
                 }
                 d[i]/=2;
                 T.addline(s,i,-d[i]),sum-=d[i]; 
          }else
          if (d[i]>0) 
          {
                 if (d[i]%2) 
                 {
                       if (t2!=-1) return false;
                       t2=i,d[i]++;
                 }
                 d[i]/=2;
                 T.addline(i,e,d[i]),sum+=d[i];  
          }
       sum/=2;
       if (t1>=0 && t2==-1 || t1==-1 && t2>=0) return false;
       if (T.MaxFlow(s,e)==sum) return true;
                          else  return false; 
}
int main()
{         
       int s,e,C,m,cases,i,n,d[50],x,y,tp; 
       char ss[22];    
       scanf("%d",&C);
       for (cases=1;cases<=C;cases++)
       {
                scanf("%d",&n);
                s=30,e=31;
                T.initial(e);
                memset(d,0,sizeof(d));
                memset(used,false,sizeof(used));
                for (i=0;i<=40;i++) father[i]=i;
                while (n--)
                {
                       scanf("%s%d",ss,&tp);
                       x=ss[0]-'a',y=ss[strlen(ss)-1]-'a';
                       d[x]--,d[y]++;
                       father[getfather(x)]=getfather(y);
                       used[x]=used[y]=true;
                       m=getfather(x);
                       if (tp) T.addline(x,y,1);
                }
                printf("Case %d: ",cases);
                if (judge(s,e,m,d,26)) printf("Well done!\n");
                                 else  printf("Poor boy!\n"); 
       }
       return 0;
}

抱歉!评论已关闭.