您的位置:首页 > 其它

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

2017-11-14 13:17 260 查看
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好用。也比较好
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  搜索