大致题意:
一个无向图n个点,m条边,求任意两个点之间最短路的最大值。
大致思路:
比赛时以为要有什么牛逼的算法才能做出这道题。后来算了下效率,发现用spfa求出n个点的最短路就可以了。
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
const int nMax=1050;
const int mMax=30050;
const int inf=1<<28;
class nodea{
public:
int id;
nodea *p[26];
nodea(){
int i;
id=-1;
for(i=0;i<26;i++)p[i]=NULL;
}
};
nodea *root;
int cnt;
int insert(char *s){
int i;
nodea *r=root;
int l=strlen(s);
for(i=0;i<l;i++){
if(r->p[s[i]-'A']==NULL){
r->p[s[i]-'A']=new nodea();
}
r=r->p[s[i]-'A'];
}
if(r->id==-1){
r->id=cnt;
cnt++;
}
return r->id;
}
struct{
int u,v, next;
int w;
}edge[mMax];
int n, k, head[nMax];
int dis[nMax];
int que[nMax],m,sum[nMax];
bool vis[nMax];
void addedge(int a,int b,int w){
edge[k].w = w;
edge[k].u=a;
edge[k].v=b;
edge[k].next=head[a];
head[a]=k;k++;
}
void spfa(int s){
int i, hhead = 0, tail = 1;
for(i = 1; i <= n; i ++){
dis[i] = inf;
vis[i] = false;
}
dis[s] = 0;
que[0] = s;
vis[s] = true;
while(hhead != tail){
int u = que[hhead];
vis[u] = false;
for(i=head[u];i!=0;i=edge[i].next){
int v = edge[i].v;
if(dis[v] >dis[u] + edge[i].w){
dis[v] = dis[u] + edge[i].w;
if(!vis[v]){
vis[v] = true;
que[tail ++] = v;
if(tail == nMax) tail = 0;
}
}
}
hhead++;
if(hhead ==nMax) hhead = 1;
}
}
char str[50],str1[50];
int main(){
int i,j,m,a,b,c;
while(cin>>n&&n)
{
k=1;
cnt=1;
root=new nodea();
memset(head,0,sizeof(head));
for(i=0;i<n;i++)
{
scanf("%s",str);
}
cin>>m;
while(m--)
{
scanf("%s%s",str,str1);
a=insert(str);
b=insert(str1);
addedge(a,b,1);
addedge(b,a,1);
}
int ans=0;
for(i=1;i<=n;i++)
{
spfa(i);
for(j=1;j<=n;j++)
{
ans=max(ans,dis[j]);
}
}
if(ans==inf)ans=-1;
cout<<ans<<endl;
}
return 0;
}