FFF at Valentine
题意:迷之题意,我还以为是判断图里有没有环,然后看讨论,说是一条路将所有的点走完。。。然后死了。结果题意是:在图里任选两点都有从其中一个点到另外一个点的路。任意一条就行了。
好吧。
思路:可以考虑到,如果某些点成环的话,那么这个环里的所有点都是两两可达的(一个强连通分量),然后考虑不同的强连通分量,如果两两强连通分量之间有边可达的话,说明所有的点两两可达。
所以:Tarjan直接缩点,然后再从每一个强连通分量建一个新的图,再深搜这个图,如果一次性能把所有的图搜完的话,说明这是可行的,或者,不行。
由于数据可能有点水,可以暴力dfs,再去判。。也是可以的(第二个代码)。
#include <iostream>
#include <vector>
#include <stdio.h>
#include <queue>
#include <string.h>
#include <algorithm>
#define MAXX 10000000
#define siz 1005
using namespace std;
template<class T>
inline bool scan_d(T &ret)
{
char c;
int sgn;
//if(c = getchar(),c == EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c = getchar();
sgn = (c=='-')?1:-1;
ret = (c == '-') ? 0:(c-'0');
while(c = getchar(),c>='0'&&c<='9') ret = ret *10 + (c - '0');
ret *= sgn;
return 1;
}
int n,m;
int vis[siz];
int indu[siz],save[siz];
struct Edge
{
int to,nex;
} edge[siz*60];
int head[siz],tot;
int Low[siz],DFN[siz],Stack[siz];
int Belong[siz];
int Index,top;
int scc;//强连通分量个数
bool Instack[siz];
vector<int>vec[siz];
void addedge(int u,int v)
{
edge[tot].to = v;
edge[tot].nex = head[u];
head[u] = tot++;
}
void Tarjan(int u)
{
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u]; i!=-1; i = edge[i].nex)
{
v = edge[i].to;
if(!DFN[v])
{
Tarjan(v);
if(Low[u] > Low[v]) Low[u] = Low[v];
}
else if(Instack[v] && Low[u] > DFN[v])
{
Low[u] = DFN[v];
}
}
if(Low[u] == DFN[u])
{
scc++;
do
{
v = Stack[--top];
Instack[v] = false;
Belong[v] = scc;
//num[scc]++;
}
while(v!=u);
}
}
void dfs(int u,int num,bool &yes){
if(num == scc){
yes = 1;return;
}
int len = vec[u].size();
for(int i=0;i<len;i++){
int v = vec[u][i];
if(!vis[v]){
vis[v] = 1;
dfs(v,num+1,yes);
vis[v] = 0;
}
}
}
void solve()
{
for(int i=1;i<=n;i++){
vec[i].clear();
}
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
//memset(num,0,sizeof(num));
Index = scc = top = 0;
for(int i=1; i<=n; i++)
{
if(!DFN[i])
{
Tarjan(i);
}
}
for(int i=1;i<=n;i++){
//cout<<Belong[i]<<" --"<<i<<" "<<scc<<endl;
indu[i] = 0;
}
for(int i=1; i<=n; i++)
{
for(int j = head[i]; j!=-1; j = edge[j].nex)
{
int v = edge[j].to;
if(Belong[i]!=Belong[v])
{
vec[Belong[i]].push_back(Belong[v]);
indu[Belong[v]]++;
//cout<<Belong[v]<<"------- "<<i<<endl;
}
}
}
int cnt = 0;
for(int i=1;i<=scc;i++){
//if(i==3) cout<<indu[i]<<endl;
if(indu[i] == 0){
cnt++;
save[cnt] = i;
}
}
//cout<<cnt<<endl;
bool yes = 1;
if(cnt>1){
yes = 0;
}
if(yes){
memset(vis,0,sizeof(vis));
yes = 0;
vis[save[cnt]] = 1;
dfs(save[cnt],1,yes);
}
if(yes){
puts("I love you my love and our love save us!");
}
else{
puts("Light my fire!");
}
}
int main()
{
int T;
scanf("%d",&T);
//scan_d(T);
while(T--)
{
scanf("%d %d",&n,&m);
//scan_d(n);
//scan_d(m);
tot = 0;
scc = 0;
memset(head,-1,sizeof(head));
//cout<<m<<" -----"<<endl;
for(int i=1; i<=m; i++)
{
//cout<<i<<endl;
int u,v;
scanf("%d%d",&u,&v);
//scan_d(u);
//scan_d(v);
addedge(u,v);
}
solve();
}
return 0;
}
暴力搜也能过。。
#include <iostream>
#include <vector>
#include <stdio.h>
#include <queue>
#include <string.h>
#include <algorithm>
#define MAXX 10000000
#define siz 1005
using namespace std;
template <class T>
inline void scan_d(T &ret)
{
char c;
ret = 0;
while ((c = getchar()) < '0' || c > '9');
while (c >= '0' && c <= '9')
{
ret = ret * 10 + (c - '0'), c = getchar();
}
}
vector<int>E[siz];
int vis[siz];
int n,m;
int dist[siz][siz];
void addedge(int u,int v)
{
E[u].push_back(v);
}
void dfs(int to,int fa){
int len = E[to].size(),v;
for(int i=0;i<len;i++){
v = E[to][i];
if(!vis[v]){
vis[v] = 1;
dist[fa][v] = 1;
dfs(v,fa);
}
}
}
int main()
{
int T;
//scanf("%d",&T);
scan_d(T);
while(T--)
{
//scanf("%d%d",&n,&m);
scan_d(n);
scan_d(m);
int a,b;
int i,j;
for(i=0; i<=n; i++)
{
E[i].clear();
}
//memset(is,0,sizeof(is));
for(i=0; i<m; i++)
{
//scanf("%d%d",&a,&b);
scan_d(a);
scan_d(b);
addedge(a,b);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
vis[j] = 0;
dist[i][j] = 0;
}
vis[i] = 1;
dfs(i,i);
}
bool flag = true;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(dist[i][j] == 1 || dist[j][i] == 1){
continue;
}
else{
// cout<<i<<" "<<j<<" "<<dist[i][j]<<" "<<dist[j][i]<<endl;
flag = 0;
break;
}
}
if(!flag) break;
}
if(flag){
puts("I love you my love and our love save us!");
}
else{
puts("Light my fire!");
}
}
return 0;
}