zoukankan      html  css  js  c++  java
  • 51Nod 1694: 两条路径(图论)

    题目链接

    Bob的哥哥住在法国。在法国有n个城市,有n-1条双向道路连通这些城市。这些城市从1~n编号。你能沿着这些道路从一个城市走到任意一个城市。 
    Bob的哥哥供职于“两条路”公司,并且刚好拿到了去修缮法国的任意两条路径的项目。一条路径指的是连通两个不同的城市的道路序列。公司能自主选择要修缮的道路,唯一的条件是这两条路径不能交叉(即不能有共同的城市)。
    当然,我们都知道存在利润,“两条路”公司得到的利润将等于两条路径的长度的乘积。假设每条道路的长度等于1,并且路径的长度等于道路的数量。请你为这公司获得最大的利润。

    输入

    单组测试数据。
    第一行是一个整数 n (2≤n≤200) ,n是这个国家的城市的数量。
    接下来n-1行是道路的信息,每一行是两个整数ai,bi,它们是城市的编号,表示ai和bi之间有一条道路直接连通。(1≤ai,bi≤n)。

    输出

    输出最大的利润。

    输入样例

    4
    1 2
    2 3
    3 4

    输出样例

    1

    解题思路:

    题目要求找到两条路径的长度乘积最大, 数据量较小,可以暴力去掉每一条边,把图分成两部分,再求两个图的深度相乘,取最大值。

    #include <stdio.h>
    #include <vector>
    #include <queue>
    #include <string.h>
    #include <algorithm> 
    const int N = 220;
    using namespace std;
    struct edge {
    	int st;
    	int l;
    	edge (){}
    	edge (int st, int l):st(st), l(l){}
    };
    vector<int>e[N];
    bool book[N];
    int n;
    int BFS(int v, int f) 
    {
    	queue<edge>q;
    	int s;
    	memset(book, false, sizeof(book));
    	q.push(edge(v, 0));
    	book[v]=book[0]=true; 
    	int temp=0;
    	while (!q.empty()) {
    		edge &u=q.front();
    		q.pop(); 
    		s=u.st;
    		temp=max(temp, u.l);
    		
    		for (int i=0; i<e[s].size(); i++) {
    			
    			if(book[e[s][i]]==false) {
    				book[e[s][i]]=true;
    				q.push(edge(e[s][i], u.l+1));
    			}
    		}
    	}
    	if(f==1)
    		return s;
    	if(f==2)
    		return temp;	
    }
    void init()
    {
    	int u, v;
    	for (int i=0; i<=n; i++)
    		e[i].clear();
    	for (int i=1; i<n; i++) {
    		scanf("%d%d", &u, &v);
    		e[u].push_back(v);
    		e[v].push_back(u);
    	}
    }
    int cut(int u, int v)
    {
    	int s=e[u][v];
    	int t;
    	e[u][v]=0;
    	for(int i=0; i<e[s].size(); i++)
    		if(e[s][i]==u) {
    			t=i;
    			e[s][i]=0;
    			break;
    		}
    	int start1=BFS(u, 1);
    	int sum1=BFS(start1, 2);
    	int start2=BFS(s, 1);
    	int sum2=BFS(start2, 2);
    	e[u][v]=s;
    	e[s][t]=u;
    	return sum1*sum2;
    	
    }
    int main()
    {
    	int ans;
    	while(scanf("%d", &n)!=EOF) {
    		init();
    		ans=0;
    		for(int i=1; i<=n; i++) {
    			for(int j=0; j<e[i].size(); j++)
    				ans=max(ans, cut(i, j));
    		}
    		printf("%d
    ", ans);
    	}	
    	return 0;
    } 
  • 相关阅读:
    【转】编写高质量代码改善C#程序的157个建议——建议27:在查询中使用Lambda表达式
    python的reduce()函数
    SpringBoot中的配置文件
    23种设计模式概况性应用场景
    设计模式---合成模式
    tmpfs(转)
    Nginx配置文件(nginx.conf)配置详解
    Java设计模式------策略模式
    ubuntu下操作端口的方法
    ubuntu下安装ssh服务器方法
  • 原文地址:https://www.cnblogs.com/zyq1758043090/p/11852496.html
Copyright © 2011-2022 走看看