您的位置:首页 > 其它

USACO 1.3 Wormholes

2015-01-22 15:12 211 查看
看似是水题,反正我用了2小时才AC……愁死了……而且看题解好像很简答的样子,但是我又没看懂啊啊啊啊啊啊啊……

拆点,DFS穷举所有情况,然后tarjan判环…… 顺便复习了tarjan..但是显然判断是否有环有更好的办法。 比如题解的方法……回头研究一下题解的方法,看起来非常简单的样子。

题解穷举所有配对的方法也简单高效……

题解的穷举配对方法和我意思一样,题解的小技巧是没有拆点,而是用2个数组,记录这个点走wormhole所能到的点,和他右方的点分别是谁。然后在判断是否有环的时候,就直接走N步,如果没有环一定走到特殊点了。(因为走到尽头就走到0了,0作为特殊点也不奇怪……因为数组初始化是0 )

/*
TASK:wormhole
LANG:C++
*/
#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;

struct point
{
int x, y;
}a[15];
int n, ans(0);

bool operator < (point A, point B)
{
if (A.x != B.x)	return A.x < B.x;
return A.y < B.y;
}

int next[30],vis[15];
int DFN[30], LOW[30], my_stack[30], instack[30];
int flag, Dindex, Stop;

void tarjan(int k)
{
DFN[k] = LOW[k] =  ++Dindex;
instack[k] = 1;
my_stack[++Stop] = k;
int next_point = next[k];
if (next_point != -1)
{
if (!DFN[next_point])
{
tarjan(next_point);
LOW[k] = min(LOW[k], LOW[next_point]);
}else if (instack[next_point] && DFN[k] > LOW[next_point])	LOW[k] = DFN[next_point];
}
if (DFN[k] == LOW[k])
{
int count = 0, tmp;
do
{
tmp = my_stack[Stop --];
++ count;
instack[tmp] = 0;
}while (tmp != k);
if (count > 1)	flag = 1;
}
}

void check()
{
flag = 0;
memset(DFN, 0, sizeof(DFN));
memset(LOW, 0, sizeof(LOW));
memset(my_stack, 0, sizeof(my_stack));
Dindex = 0;
Stop = 0;
for (int i = 0; i != 2 * n; ++ i)
{
if (!DFN[i] && !flag)	tarjan(i);
}
ans += flag;
}

void dfs(int k)
{
if (k == n)
{
check();

return;
}
if (vis[k] != -1)
{
dfs(k + 1);
return;
}
for (int i = 0; i != n; ++ i)
{
if (vis[i] != -1 || k == i)	continue;
vis[i] = k;
vis[k] = i;
next[k] = i + n;
next[i] = k + n;
dfs(k + 1);
next[k] = -1;
next[i] = -1;
vis[i] = -1;
vis[k] = -1;
}
}

int main()
{
freopen("wormhole.in", "r", stdin);
freopen("wormhole.out", "w", stdout);
cin >> n;
for (int i = 0; i != n; ++ i)	cin >> a[i].y >> a[i].x;
sort(a, a + n);
memset(next, -1, sizeof(next));
memset(vis, -1, sizeof(vis));
for (int i = 1; i != n; ++ i)
if (a[i].x == a[i - 1].x)	next[i - 1 + n] = i;
dfs(1);
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: