SRM 452 DIV2
Problems 1000
题目:
http://www.topcoder.com/stat?c=problem_statement&pm=10572&rd=13906
解答:
If there exist loop formed by required edges or node with degree > 2, then the answer is 0.
If there are no loops and no nodes with degree > 2, then the graph will consist of S separate nodes and C chains.
We need to count the number of ways to concatenate them to form a single path. We have (S+C)! ways to order them,
and for each chain we have 2 orientations, so the answer is (S+C)!*2^C
解答非常好理解,问题为判断是否存在环的形式。
#include <iostream>
#include <vector>
#include <string>
using namespace std;
bool vis[100];
int d[100];
vector <string> road;
int n;
class HamiltonPath
{
void dfs(int now)
{
vis[now]=true;
for (int i=0;i<n;i++)
if ((road[now][i]=='Y')&&(!vis[i])) dfs(i);
}
public:
int countPaths(vector <string> roads)
{
road=roads;
memset(vis,false,sizeof(vis));
n=roads.size();
for (int i=0;i<n;i++)
{
int s=0;
for (int j=0;j<n;j++)
if (roads[i][j]=='Y') s++;
if (s>2) return 0;
d[i]=s;
}
int tot1=0,tot2=0;
for (int i=0;i<n;i++)
if ((!vis[i])&&(d[i]<2))
{
dfs(i);
if (d[i]==0) tot1++;
else tot2++;
}
for (int i=0;i<n;i++)
if (!vis[i]) return 0;
long long ans=1;
for (long long i=0;i<tot1+tot2;i++) ans=(ans*(i+1)) % 1000000007;
for (int i=0;i<tot2;i++)
ans=(ans*2) % 1000000007;
return ans;
}
};
一个很精彩的答案,利用深度优先搜索,同时只有度数为1 和0 的点才作为深度优先搜索的起始点,所以当存在内环的时候,没有一个
点有资格成为搜索起始点,然后再判断是否遍历了整个点集空间。思想非常简单,代码书写也非常好!
一定要牢记这句!! You can find cycles using DFS.