UVALive - 6116 Pattern Lock

 UVALive - 6116  Pattern Lock  题目链接 http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=37383


//题意是先判断图是否联通,其次看是否根据边能够 构成 一个合法的图 不能多边少边
//其中如果原图是 2-1-3  那么 实际看起来 1-2 2-3 1-3 都可以看作是相连的
//根据这个特性,若原图中含边2-1 2-3 我们可以给它补上1-3
//其次,在得到一条合法路径后,用之构建一个图时,如果路径是1-3,那么我们可以补上(1-2,2-3)道理同上
//从而在分别给原图与新图补边后,我们得到两个与我们视觉上看起来一样的图,如果两者完全匹配,就OK,反之NO
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;


int n;


int given_map[10][10];


int connect_map[10][10];


int m=0;
int cnt;
int state;
int tmp[10];
int f[10][2];
int vis_1[10]; 


vector <int> map[10]; 


queue <int > single_head;
int vis[10];


int  query(int x,int y)  //          查询x与y是否联通
{
    if (x==y) return 1;          //自己与自己属于连通 
  vector<int>::iterator final = find( map[x].begin(), map[x].end(), y ); //查找y 
  if (final!=map[x].end()) return 1;        //找到为连通
  
  int i;
  for (i=0;i<map[x].size();i++)    //遍历map[x] vector
  { 
  if (  vis[ map[x][i]  ] ==0    )       // vis[]=0 表示没遍历过该点
  {
  vis[  map[x][i] ] =1;          //标记已经遍历过,下次不再进入此点
  int ans=query( map[x][i] ,y);    //   递归查找
  if (ans)  return 1;
  }
  
  }
  return 0;
  
}
int flag;


void linkmap()              //把原图connect 补好,便于后面 与 新构造的图对比
{
    if(vis_1[2]&&given_map[2][1]&&given_map[2][3])
        given_map[1][3]=given_map[3][1]=1;
    if(vis_1[8]&&given_map[8][7]&&given_map[8][9])
        given_map[9][7]=given_map[7][9]=1;
    if(vis_1[4]&&given_map[4][1]&&given_map[4][7])
        given_map[1][7]=given_map[7][1]=1;
    if(vis_1[6]&&given_map[6][3]&&given_map[6][9])
        given_map[3][9]=given_map[9][3]=1;
    if(vis_1[5]&&given_map[2][5]&&given_map[5][8])
        given_map[2][8]=given_map[8][2]=1;
    if(vis_1[5]&&given_map[6][5]&&given_map[5][4])
        given_map[6][4]=given_map[4][6]=1;
    if(vis_1[5]&&given_map[1][5]&&given_map[5][9])
        given_map[9][1]=given_map[1][9]=1;
    if(vis_1[5]&&given_map[7][5]&&given_map[5][3])
        given_map[3][7]=given_map[7][3]=1;
}


void create_full()  //         把得到的新图补齐
{
 if(vis[2]&&connect_map[2][1]&&connect_map[2][3])
        connect_map[1][3]=connect_map[3][1]=1;
    if(vis[8]&&connect_map[8][7]&&connect_map[8][9])
        connect_map[9][7]=connect_map[7][9]=1;
    if(vis[4]&&connect_map[4][1]&&connect_map[4][7])
        connect_map[1][7]=connect_map[7][1]=1;
    if(vis[6]&&connect_map[6][3]&&connect_map[6][9])
        connect_map[3][9]=connect_map[9][3]=1;
    if(vis[5]&&connect_map[2][5]&&connect_map[5][8])
        connect_map[2][8]=connect_map[8][2]=1;
    if(vis[5]&&connect_map[6][5]&&connect_map[5][4])
        connect_map[6][4]=connect_map[4][6]=1;
    if(vis[5]&&connect_map[1][5]&&connect_map[5][9])
        connect_map[9][1]=connect_map[1][9]=1;
    if(vis[5]&&connect_map[7][5]&&connect_map[5][3])
        connect_map[3][7]=connect_map[7][3]=1;
    if(connect_map[1][3]||connect_map[3][1])
        connect_map[1][2]=connect_map[2][1]=connect_map[2][3]=connect_map[3][2]=1;
    if(connect_map[1][7]||connect_map[7][1])
        connect_map[4][7]=connect_map[7][4]=connect_map[1][4]=connect_map[4][1]=1;
    if(connect_map[9][3]||connect_map[3][9])
        connect_map[9][6]=connect_map[6][9]=connect_map[6][3]=connect_map[3][6]=1;
    if(connect_map[7][9]||connect_map[9][7])
        connect_map[7][8]=connect_map[8][7]=connect_map[8][9]=connect_map[9][8]=1;
    if(connect_map[1][9]||connect_map[9][1])
        connect_map[1][5]=connect_map[5][1]=connect_map[5][9]=connect_map[9][5]=1;
    if(connect_map[7][3]||connect_map[3][7])
        connect_map[7][5]=connect_map[5][7]=connect_map[5][3]=connect_map[3][5]=1;
    if(connect_map[8][2]||connect_map[2][8])
        connect_map[5][2]=connect_map[2][5]=connect_map[8][5]=connect_map[5][8]=1;
    if(connect_map[4][6]||connect_map[6][4])
        connect_map[4][5]=connect_map[5][4]=connect_map[5][6]=connect_map[6][5]=1;
}










int search_legal(int x,int y)               //查询 在解锁规则中 x与y能否连接


if (x==1)
{
if (y==2&&!vis[2]) return 1;
if (y==3&&!vis[3]) if (vis[2])  return 1;
if (y==4&&!vis[4]) return 1;
if (y==5&&!vis[5]) return 1;
if (y==6&&!vis[6]) return 1;
if (y==7&&!vis[7]) if (vis[4])  return 1;
if (y==8&&!vis[8]) return 1;
if (y==9&&!vis[9]) if (vis[5]) return 1;
}
if (x==2)
{
if (y==1&&!vis[1]) return 1;
if (y==3&&!vis[3]) return 1;
if (y==4&&!vis[4]) return 1;
if (y==5&&!vis[5]) return 1;
if (y==6&&!vis[6]) return 1;
if (y==7&&!vis[7]) return 1;
if (y==8&&!vis[8]) if (vis[5]) return 1;
if (y==9&&!vis[9]) return 1;
}
if (x==3)
{
if (y==1&&!vis[1]) if (vis[2]) return 1;
if (y==2&&!vis[2]) return 1; 
if (y==4&&!vis[4]) return 1;
if (y==5&&!vis[5]) return 1;
if (y==6&&!vis[6]) return 1;
if (y==7&&!vis[7]) if (vis[5])  return 1;
if (y==8&&!vis[8]) return 1;
if (y==9&&!vis[9]) if (vis[6]) return 1;



if (x==4)
{
if (y==1&&!vis[1]) return 1;
if (y==2&&!vis[2]) return 1; 
if (y==3&&!vis[3]) return 1;
if (y==5&&!vis[5]) return 1;
if (y==6&&!vis[6]) if (vis[5]) return 1;
if (y==7&&!vis[7]) return 1;
if (y==8&&!vis[8]) return 1;
if (y==9&&!vis[9]) return 1;

if (x==5)
{
if (y==1&&!vis[1]) return 1;
if (y==2&&!vis[2]) return 1; 
if (y==3&&!vis[3]) return 1;
if (y==4&&!vis[4]) return 1;
if (y==6&&!vis[6]) return 1;
if (y==7&&!vis[7]) return 1;
if (y==8&&!vis[8]) return 1;
if (y==9&&!vis[9]) return 1;


if (x==6)
{
if (y==1&&!vis[1]) return 1;
if (y==2&&!vis[2]) return 1; 
if (y==3&&!vis[3]) return 1;

if (y==4&&!vis[4]) if (vis[5]) return 1;

if (y==5&&!vis[5]) return 1;
if (y==7&&!vis[7]) return 1;
if (y==8&&!vis[8]) return 1;
if (y==9&&!vis[9]) return 1;


if (x==7)
{
if (y==1&&!vis[1]) if (vis[4])   return 1;
if (y==2&&!vis[2]) return 1; 
if (y==3&&!vis[3]) if (vis[5]) return 1;
if (y==4&&!vis[4]) return 1;
if (y==5&&!vis[5]) return 1;
if (y==6&&!vis[6]) return 1;

if (y==8&&!vis[8]) return 1;
if (y==9&&!vis[9]) if (vis[8]) return 1;

if (x==8)
{
if (y==1&&!vis[1]) return 1;
if (y==2&&!vis[2]) if (vis[5]) return 1; 
if (y==3&&!vis[3]) return 1;
if (y==4&&!vis[4]) return 1;
if (y==5&&!vis[5]) return 1;
if (y==6&&!vis[6]) return 1;
if (y==7&&!vis[7]) return 1;

if (y==9&&!vis[9]) return 1;

if (x==9)
{
if (y==1&&!vis[1]) if (vis[5]) return 1;
if (y==2&&!vis[2]) return 1; 
if (y==3&&!vis[3]) if (vis[6]) return 1;
if (y==4&&!vis[4]) return 1;
if (y==5&&!vis[5]) return 1;
if (y==6&&!vis[6]) return 1;
if (y==7&&!vis[7]) if (vis[8])  return 1;
if (y==8&&!vis[8]) return 1;




return 0;
}
 
int macth_two()        //查询新图与原图是否完全匹配,匹配则说明能构造原图,反之不能
{
 int i,j;
    for(  i=1;i<=9;i++)
        for( j=1;j<=9;j++)
           if(connect_map[i][j]!=given_map[i][j])
                return 0;
    return 1;


}


 
int  construct(int y)          //构建新图的函数



tmp[++cnt]=y;
  vis[y]=1;


  

if (cnt==m)           /// 把所有点已经连接完后 
{

memset(connect_map,0,sizeof(connect_map));


int i;
for (i=1;i<=m;i++)
{
connect_map[tmp[i]][tmp[i-1]]=1;          //
connect_map[tmp[i-1]][tmp[i]]=1;  // 相邻的两个点 都在图中连接
}


create_full();                                  // 把新图补齐


if (macth_two())   //查询匹配
{
flag=1;
return 1;
}
else
{
vis[y]=0;
return 0;
}


  int i;
  for (i=1;i<=9;i++)    //遍历map[x] vector           
  { 
  if (given_map[y][i])
  {
 // printf("%d\n",i);
  int tm=search_legal(y,i);
  if (  vis[i ] ==0  && tm==1   )       // vis[]=0 表示没遍历过该点
  {
  //vis[ y] =1;          //标记已经遍历过,下次不再进入此边
  int ans=construct(i);    //   递归查找

  if (ans)  return 1;
      cnt--;          //  之前忘记了cnt--  递归出来后要减掉
 // cnt--;


  
  }
  }
  
  }
  
  
 
  vis[y]=0;
  if (flag) return 1;
  return 0;
  
}




int main()
{

int a,b;
int i,j,k,t,c;
scanf("%d",&t);

for (k=1;k<=t;k++)

for (i=0;i<=9;i++)
{
map[i].clear();
}
memset(vis_1,0,sizeof(vis_1));
memset(given_map,0,sizeof(given_map));
memset(f,0,sizeof(f));
scanf("%d",&n);
int choose;
for (i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
f[i][0]=a;
f[i][1]=b; 
given_map[a][b]=1;
given_map[b][a]=1;              
vis_1[a]++;  //标记出现过次数
vis_1[b]++;
map[b].push_back(a);
map[a].push_back(b);



choose=a; //随便选一个数


linkmap();

int ans;
int cun=0,connect=0;
for (i=1;i<=9;i++)
{


memset(vis,0,sizeof(vis));
if (vis_1[i])                               

ans=query(choose,i);    // 查询每一个点与别的全部数是否联通,如果是,则整个图联通,反之则否
if (ans==1)  cun++;
}
}



  m=0;
for (i=1;i<=9;i++)



if (vis_1[i])  m++;   //计算总共几个点
}





if (cun==m)  connect=1;   //联通图       

if (connect==0) //先判断是否联通
{
printf("IMPOSSIBLE\n");
continue;
}
 
for (i=1;i<=9;i++)      //把每一个点作为开头,去搜索得到一条 合法路径,然后用该路径 构造出一个新图,与原图匹配,看是否完全匹配

if (vis_1[i])
{
 
cnt=0;
flag=0;
memset(tmp,0,sizeof(tmp));
memset(vis,0,sizeof(vis));
construct(i);  
 if (flag) break;
 
}

}

if (flag==1)
{
for (i=1;i<=m;i++)
{
 
printf("%d ",tmp[i]);
}
printf("\n");
continue;

}
else
{
printf("IMPOSSIBLE\n");
continue;
}





}


return 0;


}

你可能感兴趣的:(UVALive - 6116 Pattern Lock)