题目链接:
http://codeforces.com/problemset/problem/516/B
题解:
首先可以得到一个以‘.’为点的无向图,当存在一个点没有边时,无解。然后如果这个图边双联通无唯一解。
同时观察可知,只有一条边的点只有唯一一种连法,所以我们可以直接将其与其相连点从图中删除,再考虑剩下图中是否还有只有一条边的点,直到所有的结点都被删除,或剩下双联通分量以及存在没有边的结点为止。
正确性……显然吧。时间复杂度$O(n^{2})$。
代码:
1 #include<cstdio> 2 inline int read(){ 3 int s=0,k=1;char ch=getchar(); 4 while(ch<‘0‘||ch>‘9‘) k=ch==‘-‘?-1:k,ch=getchar(); 5 while(ch>47&&ch<=‘9‘) s=s*10+(ch^48),ch=getchar(); 6 return s*k; 7 } 8 const int N=2010; 9 int n,m; 10 char map[N][N]; 11 char result[N][N]; 12 struct node { 13 int x,y; 14 }; 15 node q[N*N]; 16 int l,r; 17 int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1}; 18 char z[8]={‘^‘,‘v‘,‘<‘,‘>‘,‘v‘,‘^‘,‘>‘,‘<‘}; 19 int pan(int x,int y){ 20 int ans=0; 21 for(int i=0;i<4;i++){ 22 int nx=x+xx[i],ny=y+yy[i]; 23 if(map[nx][ny]==‘.‘) ans++; 24 } 25 return ans; 26 } 27 inline bool solve(){ 28 int sum=0; 29 for(int i =1;i<=n;i++) 30 for(int j=1;j<=m;j++){ 31 if(map[i][j]==‘*‘){ 32 result[i][j]=map[i][j]; 33 continue; 34 } 35 sum++; 36 int t=pan(i,j); 37 if(t==0) return 0; 38 else if(t==1) q[r++]=(node){i,j}; 39 } 40 if(sum&1) return false; 41 int t=0; 42 while(l<r){ 43 node now=q[l++]; 44 int x=now.x,y=now.y; 45 if(map[x][y]!=‘.‘) continue; 46 for(int i=0;i<4;i++){ 47 int nx=x+xx[i],ny=y+yy[i]; 48 if(map[nx][ny]==‘.‘){ 49 t++; 50 map[x][y]=0; 51 map[nx][ny]=0; 52 result[x][y]=z[i]; 53 result[nx][ny]=z[i+4]; 54 for(int j=0;j<4;j++){ 55 int tx=nx+xx[j],ty=ny+yy[j]; 56 if(map[tx][ty]==‘.‘){ 57 int t=pan(tx,ty); 58 if(t==1) q[r++]=(node){tx,ty}; 59 if(t==0) return false; 60 } 61 } 62 break; 63 } 64 if(i==3) return false; 65 } 66 } 67 return t>=sum/2; 68 } 69 int main(){ 70 n=read(),m=read(); 71 for(int i=1;i<=n;result[i][m+1]=‘\n‘,i++) 72 scanf("%s",map[i]+1); 73 bool ans=solve(); 74 // printf("\n"); 75 if(ans){ 76 for(int i=1;i<=n;i++) 77 for(int j=1;j<=m+1;j++){ 78 printf("%c",result[i][j]); 79 } 80 } 81 else printf("Not unique\n"); 82 }
时间: 2024-10-14 12:10:23