USACO 2004 February - Cow Marathon(bfs求树的直径)
题目链接:传送门
题意:
有N个农田以及M条路,给出M条路的长度以及路的方向(对树的建立没有影响,最终还是一棵树),让你找到一条 两农田(任意的)间的路径,使得距离最长,并输出最长距离。
题解:
就是求树的直径
1. 先以任意点为起始点,bfs找到最远的s
2. 以s为起点,bfs找到最远的t,求得的s-t即为树的最大直径
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#define numm ch-48
#define pd putchar(' ')
#define pn putchar('\n')
#define pb push_back
#define fi first
#define se second
#define fre1 freopen("1.txt","r",stdin)
#define fre2 freopen("2.txt","w",stdout)
using namespace std;
template <typename T>
void read(T &res) {
bool flag=false;char ch;
while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
flag&&(res=-res);
}
template <typename T>
void write(T x) {
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int maxn=40010;
const int N=1010;
//const int M=10010;
const int inf=0x3f3f3f3f;
typedef long long ll;
struct edge {
int to,net,w;
}e[maxn<<1];
int dis[maxn],cnt=0,head[maxn];
int pos,ans,n;
bool vis[maxn];
void add(int u,int v,int w) {
e[++cnt].to=v;
e[cnt].w=w;
e[cnt].net=head[u];
head[u]=cnt;
}
void bfs(int u) {
fill(dis+1,dis+1+n,0);
fill(vis+1,vis+1+n,false);
vis[u]=true;
queue<int>que;
que.push(u);
while(!que.empty()) {
int k=que.front();
que.pop();
for(int i=head[k];i;i=e[i].net) {
int to=e[i].to;
if(!vis[to]) {
if(dis[to]<dis[k]+e[i].w)
dis[to]=dis[k]+e[i].w;
que.push(to);
vis[to]=true;
}
}
}
ans=0;
for(int i=1;i<=n;i++) {
if(ans<dis[i]) {
ans=dis[i];
pos=i;
}
}
return ;
}
int main()
{
int m;
read(n),read(m);
for(int i=1;i<=m;i++) {
int u,v,w;
read(u),read(v),read(w);
char s[5];
scanf("%s",s);
add(u,v,w);
add(v,u,w);
}
bfs(1);
bfs(pos);
write(ans);pn;
return 0;
}
所谓人生,一半惊喜,一半遗憾

浙公网安备 33010602011771号