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

POJ2513解题报告

2018年01月20日 ⁄ 综合 ⁄ 共 1443字 ⁄ 字号 评论关闭

题目的实质是要判断图中是否存在欧拉通路。所谓欧拉通路,是指一个图中,走过每个边一次且仅一次的一条路径。若一个无向图中存在欧拉通路,当且仅当(1)只有两个节点的度数为奇数(2)图是连通的。对于这个题目,色数未知,即节点数未知,但很明显,节点数<=木棒个数*2,所以设节点上限为500000。用并查集判断图的连通情况,用trie树统计颜色(即节点)个数,然后利用定理即可AC。

下面给出源代码,由于是看了某位大牛的解题报告才做出来的,所以代码有些相似- -,只怪自己太水了,不会trie树,这么水的题都 不会做。。。555555555,不过现在会了   哈哈哈哈

 

#include <iostream>
#define max 500001
using namespace std;
struct node
{
  int flag;
  node *p[26]; 
  node()
  {
    int i;
    flag=-1;
    for(i=0;i<26;i++)
      p[i]=NULL;     
  }  
}root;
int sum,rank[max],f[max],d[max];
char s1[10],s2[10];
int getnum(char *s)
{
  int i;
  node *r=&root;
  for(i=0;s[i];i++)
  {
    if(r->p[s[i]-'a']==NULL)
      r->p[s[i]-'a']=new node();
    r=r->p[s[i]-'a'];                  
  }   
  if(r->flag==-1)
    r->flag=sum++;
  return r->flag;
}
int father(int i)
{
  if(f[i]!=i)
    f[i]=father(f[i]);
  return f[i];   
}
void Union(int i,int j)
{
  i=father(i);
  j=father(j);
  if(i==j)
    return;
  if(rank[i]>rank[j])
    f[j]=i;         
  else
  {
    f[i]=j;
    if(rank[i]==rank[j])
      rank[j]++;                
  }        
}
int main()
{
  int i,j,k;
  sum=0;
  memset(rank,0,sizeof(rank));
  memset(d,0,sizeof(d));
  for(i=0;i<max;i++)
    f[i]=i;
  while(scanf("%s%s",&s1,&s2)!=EOF)
  {
    i=getnum(s1);
    j=getnum(s2);
    d[i]++;
    d[j]++;
    if(i!=j)
      Union(i,j);                                
  } 
  for(i=0,k=0;i<sum;i++)
    if(d[i]%2)
      k++;
  j=father(0);
  for(i=1;i<sum;i++)
    if(father(i)!=j)
    {
      printf("Impossible/n") ;
      return 0;              
    }
  if(k<3)
    printf("Possible/n");
  else
    printf("Impossible/n");
  return 0;
}

 

 

 

 

 

 

【上篇】
【下篇】

抱歉!评论已关闭.