环游世界

环游世界(travel)
题目描述
在Cai0715的世界里,总共有N个城市,每两个城市之间都被一条无向的道路连接。
某一天,Boboo来Cai0715的世界游玩,由于这个世界太过于神奇,使他产生了一种环游世界的冲动,但他必须按照下面的规则进行环游。
·他必须在一个城市开始环游,在另一个世界结束环游。
·他环游世界时必须经过所有的城市一次,且只能经过一次。
·他环游世界时必须经过N-1条道路,且只能经过N-1条道路。
·由于某些道路的风景非常漂亮,所以Boboo想要在他环游世界的过程中必须经过这些道路。
现在,给定你一些必须经过的道路,问Boboo环游世界的方案有多少种?
输入文件
第一行,一个数N,代表共有N个城市。
以下是一个N行N列的字符矩阵A,如果A[I][J]是Y则代表城市I和城市J之间这条道路必须被经过。
输出文件
一行,一个数,Boboo环游世界的方案数。由于最后答案可能很大,所以只需要将答案mod 1000000007 输出即可。
样例输入
3
NYN
YNN
NNN
样例输出
4
注释
5
【样例解释】
1、 1->2->3
2、 2->1->3
3、 3->1->2
4、 3->2->1
【数据范围】
对于30%的数据,2<=N<=5。
对于50%的数据,2<=N<=20。
对于100%的数据,2<=N<=50。

若不存在环,则有必用边的点可以组成多条链y,每条链有两个方向
剩余的点数和链数总和x可以全排列。
ans=A(x,x)*2^y

判断环:读入时,记录必用边的数目num*2
深搜是,记录必用边的数目num2
如果num2<>num
可以证明存在环

code:
var n:longint;
s:string;
i,j,k:longint;
map:array[1..50,1..50]of int64;
point:array[1..50]of int64;
head,tail:longint;
queue:array[1..5000]of int64;
used:array[1..50]of boolean;
a,b,ans,edge,edge2:int64;
procedure dfs(x:longint);
var i,j,k:longint;
begin for i:=1 to n do
if (map[x,i]=1)and(used[i])
then begin inc(edge);
inc(a);
used[i]:=false;
dfs(i);
end;
          end;
begin 
fillchar(map,sizeof(map),0);
fillchar(point,sizeof(point),0);
readln(n);
edge2:=0;
for i:=1 to n do
begin readln(s);
for j:=1 to n do
if s[j]='Y'
then begin map[i,j]:=1;
inc(point[i]);
inc(edge2);
if (point[i]>2)
then begin writeln(0);

halt;
end;
end;
end;
fillchar(used,sizeof(used),true);
a:=0; b:=0; edge:=0;
for i:=1 to n do
if (point[i]<>0)and(used[i])
then begin inc(b);
inc(a);
used[i]:=false;
dfs(i);
end;
if edge<>edge2 div 2
then begin writeln(0);

halt;
end;
n:=n-a+b;
ans:=1;
for i:=1 to n do
ans:=((ans mod 1000000007)*(i mod 1000000007)) mod 1000000007;
for i:=1 to b do
ans:=(ans*2) mod 1000000007;
writeln(ans);

end.


posted @ 2015-10-20 08:58  紫蜘蛛之歌  阅读(196)  评论(0编辑  收藏  举报