• 湫湫系列故事——设计风景线


    Description

      随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好。 
      现在已经勘探确定了n个位置可以用来建设,在它们之间也勘探确定了m条可以设计的路线以及他们的长度。请问是否能够建成环形的风景线?如果不能,风景线最长能够达到多少? 
      其中,可以兴建的路线均是双向的,他们之间的长度均大于0。 

    Input

      测试数据有多组,每组测试数据的第一行有两个数字n, m,其含义参见题目描述; 
      接下去m行,每行3个数字u v w,分别代表这条线路的起点,终点和长度。 

       [Technical Specification] 
      1. n<=100000 
      2. m <= 1000000 
      3. 1<= u, v <= n 
      4. w <= 1000 

    Output

      对于每组测试数据,如果能够建成环形(并不需要连接上去全部的风景点),那么输出YES,否则输出最长的长度,每组数据输出一行。 

    Sample Input

    3 3
    1 2 1
    2 3 1
    3 1 1

    Sample Output

    YES


    首先判断是否成环   如果没有环在看有几个根 也就是几个集合 (有不连通的情况)   找出所有集合中的最长链

    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int root[100001]; 
    int cut;
    int head[100001];
    int pre[100001];
    int vis[100001];
    int dist[100001];
    int ans;
    int n,m;
    struct node 
      {
       int from,to,val,next;
       }dian[2000001];
    
    
    
    void  Edge(int u,int v,int w)
    {
    	dian[cut].from =u;
    	dian[cut].to =v;
    	dian[cut].val =w;
    	dian[cut].next =head[u];
    	head[u]=cut++;
    }
    int jilu;
    void bfs(int s)
    {
    memset(vis,0,sizeof(vis));
    memset(dist,0,sizeof(dist));
    
    	queue<int>q;
    	q.push(s);vis[s]=1;dist[s]=0;
    	while(!q.empty() )
    	{
    		int u=q.front() ;
    		q.pop() ;
    		for(int i=head[u];i!=-1;i=dian[i].next )
    		{
    			int v=dian[i].to ;
    			if(!vis[v])
    			{
    				if(dist[v]<dist[u]+dian[i].val )
    				dist[v]=dist[u]+dian[i].val ;
    					vis[v]=1;
    		            q.push(v); 	
    			}
    		}
         }
    	 	ans=0;
    	for(int i=1;i<=n;i++)
    	{
    			if(ans<dist[i])
    		     {
    			    ans=dist[i];
    			    jilu=i;
    	          }
    	}
    		
    }
    int find(int x)
    {
      int r=x;         
      while(r!=pre[r]) 
      r=pre[r]; 
      int i=x,j;      
      while(i!=r) 
      {
       j=pre[i];pre[i]=r;i=j;
      }
     return r; 
    }
    int main()
    {
         
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{	
    	for(int i=0;i<=n;i++)
    	{
    		pre[i]=i;
    		}
    		cut=0;
         	memset(head,-1,sizeof(head));
           	int f=0;
           	int u,v,w;
    		for(int i=0;i<m;i++)
    		{
    			scanf("%d%d%d",&u,&v,&w);
    			if(f==0)
    			{
    					Edge(u,v,w);
    			    	Edge(v,u,w);
    			}
    			int dx=find(u) ;
    			int dy=find(v) ;
    			if(dx==dy)//判断是否成环
    		    	f=1;
    			 pre[dx]=dy;
    		}
    		if(f==1)
    		{
    			printf("YES
    ");
    			continue;
    		}
    		int shu=0;
    		for(int i=1;i<=n;i++)
    		{
    			if(i==pre[i])//查找一共有几个集合
    			root[shu++]=i;
    		}
    			int max=0;
    			for(int i=0;i<shu;i++)
    			{
    				bfs(root[i]);
    			        bfs(jilu);//找出每个集合的最长链
    			        if(max<ans)
    			        {
    			        	max=ans;
    					}
    			}
    			printf("%d
    ",max);
    	}
    	return 0; 
    }


  • 相关阅读:
    [bzoj4868][Shoi2017]期末考试
    [4.30四校联考]
    [Noi2013]快餐店
    [Noi2013]树的计数
    [Noi2013]向量内积
    [Noi2013]矩阵游戏
    java端拦截器判断客户的的请求是否是ajax请求
    spring 事务回滚
    Page directive: illegal to have multiple occurrences of contentType with different values
    jsp service bean
  • 原文地址:https://www.cnblogs.com/kingjordan/p/12027096.html
Copyright © 2020-2023  润新知