HDU5961-搜索|模拟&思维&好题-A

来源:互联网 发布:软件paris 编辑:程序博客网 时间:2024/06/05 09:04

http://acm.hdu.edu.cn/showproblem.php?pid=5961
这道题有一个地方有点乱,。
他让判断两个图是否同时是竞赛图,我就在想既然是两个,是一定有关系,
所以才是两个,所以我就在想用floyd,想着,虽然他是n3 但是他可以同时判定两个啊。
即两个图的边是互斥的。
但是这个题完全没有用到,就是用同样的算法做两遍。
是基于下列的考虑。
传递的性质可以这样利用,那就是搜索的时候,不会有任何一点
层数为2的点。
所以bfs也可以利用这个性质,dfs也可以
时间复杂度 不到3e7。
4秒正常4e7是可以跑到的。
然而我用dfs写了一下,一直T。
广搜3900ms是可以过的。还可以。
这个版本是用的定义的方法。即穷举枚举,按照定义。
但是最后一层用邻接矩阵,减少一层循环。不然肯定t
② 输入一个字符串,用scanf输入一个串 要比一个字符一个字符输入快多了。用getchar也可以。但是不要用scanf一个字符一个字符的输入。

#include <iostream>#include <stdio.h>#include <vector>#include <cstring>using namespace std;/* 这道题有一个地方有点乱,。他让判断两个图是否同时是竞赛图,我就在想既然是两个,是一定有关系,所以才是两个,所以我就在想用floyd,想着,虽然他是n3 但是他可以同时判定两个啊。即两个图的边是互斥的。但是这个题完全没有用到,就是用同样的算法做两遍。是基于下列的考虑。传递的性质可以这样利用,那就是搜索的时候,不会有任何一点层数为2的点。所以bfs也可以利用这个性质,dfs也可以时间复杂度 不到3e7。4秒正常4e7是可以跑到的。*/const int maxn=2100;vector<int>G[maxn];vector<int>g[maxn];int mpp[maxn][maxn];char a;int mpq[maxn][maxn];bool flag1,flag2;void dfs1(int u){      for(int i=0;i<G[u].size();i++){          int to=G[u][i];          for(int j=0;j<G[to].size();j++){             int to2=G[to][j];             if(mpq[u][to2]!=1){                flag1=true;                return;             }          }      }  return;}void dfs2(int u){      for(int i=0;i<g[u].size();i++){          int to=g[u][i];          for(int j=0;j<g[to].size();j++){             int to2=g[to][j];             if(mpp[u][to2]!=1){                flag2=true;return;             }          }      }  return;}void init(int m){     for(int i=0;i<=m;i++){         G[i].clear();         g[i].clear();     }     //memset(mpp,0,sizeof(mpp));     //memset(mpq,0,sizeof(mpq));}int main(){   int t,m;    scanf("%d",&t);    while(t--){          scanf("%d",&m);          getchar();          init(m);          for(int i=1;i<=m;i++){              for(int j=1;j<=m;j++){                  mpp[i][j]=0;                  mpq[i][j]=0;                  scanf("%c",&a);                  if(a=='Q'){                      g[i].push_back(j);                      mpp[i][j]=1;                      //g[j].push_back(i);                  }                  else if(a=='P'){                        G[i].push_back(j);                        mpq[i][j]=1;                        //cout<<i<<" "<<j<<endl;                       // G[j].push_back(i);                  }              }              getchar();          }          flag1=false;          //cout<<"!!"<<endl;          for(int i=1;i<=m&&!flag1;i++){              dfs1(i);          }          flag2=false;          for(int i=1;i<=m&&!flag2;i++){              dfs2(i);          }          if(!flag1&&!flag2)             puts("T");          else            puts("N");    }    return 0;}

用广搜也是可以。道理我懂,可是我用dfs模拟那个过程,即每次先把邻接的点的度数增加并且用 vis标定,再下一个循环中如果出现大于等于2的,直接godie,否则 就继续。
但是我发现这样写和前面代码 的三重循环,时间复杂度好像差不多啊。。
还是bfs好用。也比较好