试题编号: | 201709-4 |
试题名称: | 通信网络 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 某国的军队由N个部门组成,为了提高安全性,部门之间建立了M条通路,每条通路只能单向传递信息,即一条从部门a到部门b的通路只能由a向b传递信息。信息可以通过中转的方式进行传递,即如果a能将信息传递到b,b又能将信息传递到c,则a能将信息传递到c。一条信息可能通过多次中转最终到达目的地。 输入格式 输入的第一行包含两个整数N, M,分别表示部门的数量和单向通路的数量。所有部门从1到N标号。 输出格式 输出一行,包含一个整数,表示答案。 样例输入 4 4 样例输出 2 样例说明 部门1和部门4知道所有其他部门的存在。 评测用例规模与约定 对于30%的评测用例,1 ≤ N ≤ 10,1 ≤ M ≤ 20; |
最开始想着用dfs做,想着只要满足两种情况之一就可以:
①.可以到达所有点的起点
②.可以被所有的点通过dfs到达的点
后来提交以后,发现只有10分,应该是只能通过样例。于是,又试了别的例子 发现
这种情况下的结果并不对。
再次仔细读题以后,发现我忽略了一句话:
我并没有考虑到部门2知道部门4的存在,所以刚开始的想法是错误的。
于是,决定用ans[ ][ ]来判断两个部门之间是否知道彼此。最终遍历该矩阵,若一行全都是1,则说明该行对应的部门知道所有的部门。然而,我提交后发现,运行超时,只有60分。
我觉得超时的原因很有可能就在dfs这个函数中。我发现我的dfs需要遍历该点在邻接矩阵中的整行,于是我改用vector数组。再次提交,得到100分,时间也变成了140ms。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int flag[1005];
int m,n,i,j,k;
vector<int> graph[1005];
int ans[1005][1005];
int res;
void dfs(int start,int cur){
int v;
flag[start]=true;
ans[start][cur]=1;
ans[cur][start]=1;
for(v=0.;v<graph[start].size();v++){
if(flag[graph[start][v]]==false){
dfs(graph[start][v],cur);
}
}
}
int main(){
cin>>n>>m;
for(i=1;i<=n;i++){
flag[i]=false;
}
int a,b;
for(i=1;i<=m;i++){
cin>>a>>b;
graph[a].push_back(b);
}
j=1;
while(j<=n){
fill(flag,flag+n+1,0);
dfs(j,j);
j++;
}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(ans[i][j]==0) break;
}
if(j==n+1) res++;
}
cout<<res;
return 0;
}