题目链接:传送门
题意:
有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(' ') #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; }