标签:拓扑图
拓扑的思想 如果满足条件 ‘.’未遍历完之前肯定存在度为1的点(上下左右仅有一个’.’)
遍历到一个1度点u时 将与他连的点v用对应括号括起 此时v也已匹配 入度归零 同时将与v相连的其余点入度减1 不断遍历知道遍历完所有’.’
若能遍历完 则满足条件否则无解或多解
(吐槽一下 原本用的纯粹拓扑思路 想想也是绝对要T的。。后来改换BFS
代码如下:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
using namespace std;
typedef struct Point
{
int x,y;
}Point;
Point pt[4000000];
int in[2002][2002];
char mp[2002][2002];
int dirx[] = { 0, 0, 1,-1};
int diry[] = { 1,-1, 0, 0};
char ch[] = "><v^";
char st[] = "<>^v";
int m,n;
int tp;
bool iin(int x,int y) {return x > 0 && x <= m && y > 0 && y <= n;}
void rush(int x,int y)
{
int i,xx,yy,cnt = 0;
for(i = 0; i < 4; ++i)
{
xx = x+dirx[i];
yy = y+diry[i];
if(iin(xx,yy) && mp[xx][yy] == ‘.‘) cnt++;
}
in[x][y] = cnt;
}
bool topo()
{
int i,j,k,x,y,xx,yy,xxx,yyy,cnt = 0;
queue <pair<int,int> > q;
for(j = 0; j <tp; ++j)
{
x = pt[j].x;
y = pt[j].y;
if(in[x][y] == 1)
{
q.push(pair<int,int> (x,y));
in[x][y] = 0;
}
}
pair <int,int> p;
while(!q.empty())
{
p = q.front();
q.pop();
x = p.first;
y = p.second;
in[x][y]--;
for(j = 0; j < 4; ++j)
{
xx = x+dirx[j];
yy = y+diry[j];
if(iin(xx,yy) && mp[xx][yy] == ‘.‘)
{
in[xx][yy] = 0;
mp[xx][yy] = ch[j];
mp[x][y] = st[j];
for(k = 0; k < 4; ++k)
{
xxx = xx+dirx[k];
yyy = yy+diry[k];
if(iin(xxx,yyy) && mp[xxx][yyy] == ‘.‘)
{
rush(xxx,yyy);
if(in[xxx][yyy] == 1) q.push(pair<int,int>(xxx,yyy));
}
}
cnt+=2;
}
}
}
return cnt == tp;
}
int main()
{
int i,j;
scanf("%d %d",&m,&n);
tp = 0;
for(i = 1; i <= m; ++i)
{
scanf("%s",mp[i]+1);
for(j = 1; j <= n; ++j)
if(mp[i][j] == ‘.‘)
{
pt[tp].x = i;
pt[tp++].y = j;
in[i][j] = 0;
if(iin(i-1,j) && mp[i-1][j] == ‘.‘)
{
in[i-1][j]++;
in[i][j]++;
}
if(iin(i,j-1) && mp[i][j-1] == ‘.‘)
{
in[i][j-1]++;
in[i][j]++;
}
}
}
if(topo())
{
for(i = 1; i <= m; ++i) printf("%s\n",mp[i]+1);
}else puts("Not unique");
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:拓扑图
原文地址:http://blog.csdn.net/challengerrumble/article/details/47361033