2012杭州现场赛 H - Friend Chains dijkstra+邻接表

来源:互联网 发布:昆明关键字优化公司 编辑:程序博客网 时间:2024/05/16 17:24

题目出处:http://acm.hdu.edu.cn/showproblem.php?pid=4460

题意: 求任意两个点的最小值,再从求出的所有最小值中,选择一个最大的输出,若存在一个点无法到达另一个点,输出-1;

解法:直接暴力枚举出每两个点的距离。

这道题做了将近一天时间。。无奈不太懂 时间复杂度。

一般的dijkstra 应该需要两个for,即时间复杂度应该是o(n*n),再加上每个点都要进行一次(+一个for),所以时间复杂度应该是o(n*n*n).

就是 1e9 ,而1s 运行 1e8 。显然不行。

#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<map>#include<queue>#include<vector>using namespace std;const int N=1e3+10;int n,vis[N],ans,k;char aa[11],bb[11];string a,b;vector<int>road[N];map<string,int>m;queue<int>q;void init(){ans=-1;m.clear();                   //清空上一轮 m(map),road[N](vector) 内的的数据;for(int i=0;i<N;++i)while(!road[i].empty())road[i].pop_back();}void input(){for(int i=0;i<n;++i){scanf("%s",&aa);m[a=aa]=i;            //这样比直接“cin>>a”省时间}scanf("%d",&k);for(int i=0;i<k;++i){scanf("%s%s",&aa,&bb);road[m[a=aa]].push_back(m[b=bb]);   //构建邻接表road[m[b]].push_back(m[a]);}}void dijsktra(){for(int i=0;i<n;++i){memset(vis,0,sizeof(vis));while(!q.empty())q.pop();int step[N]={0};vis[i]=1;q.push(i);while(!q.empty()){int x=q.front();q.pop();for(int i=0;i<road[x].size();++i)   //邻接表进行dijkstra(压缩路径直接省略),也能算是bfs()吧;{if(!vis[road[x][i]]){q.push(road[x][i]);vis[road[x][i]]=1;step[road[x][i]]=step[x]+1;}}} for(int i=0;i<n;++i)                        //存在没有遍历的vis[i],即说明存在两个点不联通。if(!vis[i])return;for(int i=0;i<n;++i)ans=max(ans,step[i]);}}void print(){printf("%d\n",ans);}int main(){while(scanf("%d",&n)==1&&n){    init();    input();    dijsktra();    print();    }} 

加上邻接表,就能优化很多时间复杂度是 o(n*m*n),如果图不会太稠密,那么m应该就会很小,所以就接近o(n*n)。


0 0