zoukankan      html  css  js  c++  java
  • Roads in the North

    Roads in the North

    Building and maintaining roads among communities in the far North is
    an expensive business. With this in mind, the roads are build such
    that there is only one route from a village to a village that does not
    pass through some other village twice. Given is an area in the far
    North comprising a number of villages and roads among them such that
    any village can be reached by road from any other village. Your job is
    to find the road distance between the two most remote villages in the
    area.

    The area has up to 10,000 villages connected by road segments. The villages are numbered from 1.
    Input
    Input to the problem is a sequence of lines, each containing three positive integers: the number of a village, the number of a different village, and the length of the road segment connecting the villages in kilometers. All road segments are two-way.
    Output
    You are to output a single integer: the road distance between the two most remote villages in the area.
    Sample Input
    5 1 6
    1 4 5
    6 3 9
    2 6 8
    6 1 7
    Sample Output
    22

    题目大意:
    找出距离最远的两个村庄,并输出二者之间的距离。
    输入格式为:每行三个数,前两个数表示不同的村庄,最后一个数表示两个村庄之间的距离。
    输出:输出距离最远村庄二者的距离。

    解题思路:求树的直径模板题;需要两次bfs或dfs;先找到任意一个点,用bfs或dfs找到距离它最远的点并标记,然后以这个点为起点,用bfs或dfs找到距离它最远的点,输出二者之间的距离。
    需要用到链式前向星存图及其遍历图的方式。
    链式前向星存图:
    加边
    void add ( int u, int v, int w)
    {
    edge [cnt ].w = w;
    edge [cnt ]. to = v;
    edge [cnt ]. next = head [u];
    head [u] = cnt ++;
    }
    cnt初始化为0,head初始化为-1

    	**struct Edge
    	{
    		int next ;//下一条边
    		int to;//这条边的终点
    		int w;//边的权值
    	} edge [ MAXN ];**
    
    	边的遍历,遍历以u为起点的所有边
    	for (int i= head [u];~i;i= edge [i]. next )
    	{
    			cout <<u<<" ->" <<edge [i].e<< endl ;
    	}
    		倒序遍历
    

    Code:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define N 10000//数组大小要合适,不然会RE 
    using namespace std;
    struct node{
    	int w,to,next;
    };
    node edge[N];
    int cnt=0,ans=0;//如果是多组案例,cnt和ans都要更新,不更新cnt,可能会导致越界即RE 
    int vis[N],head[N];
    int dis[N];
    int temp;
    void add(int u,int v,int w){//加边 
    	edge[cnt].w=w;
    	edge[cnt].to=v;
    	edge[cnt].next=head[u];
    	head[u]=cnt++;
    }
    void bfs(int x){
    	queue<int >q;
    	q.push(x);
    	vis[x]=1;
    	dis[x]=0;
    	while(!q.empty()){
    		int u=q.front();
    		q.pop();
    		for(int i=head[u];i!=-1;i=edge[i].next){//图的遍历,倒序遍历。 
    			int v=edge[i].to;
    			if(!vis[v]){
    				if(dis[v]<dis[u]+edge[i].w){
    					dis[v]=dis[u]+edge[i].w;
    					if(dis[v]>ans){
    						ans=dis[v];//更新边 
    						temp=v;//标记端点 
    					}
    				}
    				vis[v]=1;
    				q.push(v);
    			}
    		}
    	}
    }
    int main(){
    	memset(head,-1,sizeof(head));//一定要将head[]初始化。 
    	int u,v,w;
    	while(scanf("%d %d %d",&u,&v,&w)!=EOF){//输入,用ctrl+z结束输出 
    		add(u,v,w);
    		add(v,u,w);
    		//cout<<u<<v<<w<<endl;
    	}
    	bfs(1);//第一次查找 
    	ans=0;
    	memset(vis,0,sizeof(vis));//每次查找前都要将vis,dis归零,只有在下一个案例,才能更新head[]. 
    	memset(dis,0,sizeof(dis));
    	bfs(temp);//第二次查找 
    	cout<<ans<<endl;
    	return 0;
    }
    
    七月在野,八月在宇,九月在户,十月蟋蟀入我床下
  • 相关阅读:
    Java内存泄漏分析系列之七:使用MAT的Histogram和Dominator Tree定位溢出源
    Java内存泄漏分析系列之六:JVM Heap Dump(堆转储文件)的生成和MAT的使用
    Java内存泄漏分析系列之五:常见的Thread Dump日志案例分析
    Java内存泄漏分析系列之四:jstack生成的Thread Dump日志线程状态
    Java内存泄漏分析系列之三:jstat命令的使用及VM Thread分析
    Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析
    Java内存泄漏分析系列之一:使用jstack定位线程堆栈信息
    安全框架Shiro
    JDK动态代理与CGLib动态代理
    解读分库分表中间件Sharding-JDBC
  • 原文地址:https://www.cnblogs.com/voids5/p/12695051.html
Copyright © 2011-2022 走看看