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并发编程 线程间协作
    博客园添加目录,导航,回到顶部
    汉诺塔递归实现
    java并发编程 线程基础
    Flink中算子进行Chain的规则分析(最新代码,源码版本大于1.11.2)
    Flink流处理程序在Local模式下的运行流程源码分析
    Flink-DataStream流处理应用(Local模式下)运行流程-源码分析
    Flink Streaming基于滚动窗口的事件时间分析
    Spark-2.3.2 Java SparkSQL的自定义HBase数据源
    Spark-2.3.2 HBase BulkLoad
  • 原文地址:https://www.cnblogs.com/voids5/p/12695051.html
Copyright © 2011-2022 走看看