HDOJ 4460 Friend Chains 图的最长路

类似于树的直径,从随意一个点出发,找到距离该点最远的且度数最少的点.

然后再做一次最短路

Friend Chains

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 4227    Accepted Submission(s): 1359

Problem Description

For a group of people, there is an idea that everyone is equals to or less than 6 steps away from any other person in the group, by way of introduction. So that a chain of "a friend of a friend" can be made to connect any 2 persons and it contains no more than
7 persons.

For example, if XXX is YYY’s friend and YYY is ZZZ’s friend, but XXX is not ZZZ‘s friend, then there is a friend chain of length 2 between XXX and ZZZ. The length of a friend chain is one less than the number of persons in the chain.

Note that if XXX is YYY’s friend, then YYY is XXX’s friend. Give the group of people and the friend relationship between them. You want to know the minimum value k, which for any two persons in the group, there is a friend chain connecting them and the chain‘s
length is no more than k .

Input

There are multiple cases.

For each case, there is an integer N (2<= N <= 1000) which represents the number of people in the group.

Each of the next N lines contains a string which represents the name of one people. The string consists of alphabet letters and the length of it is no more than 10.

Then there is a number M (0<= M <= 10000) which represents the number of friend relationships in the group.

Each of the next M lines contains two names which are separated by a space ,and they are friends.

Input ends with N = 0.

Output

For each case, print the minimum value k in one line.

If the value of k is infinite, then print -1 instead.

Sample Input

3
XXX
YYY
ZZZ
2
XXX YYY
YYY ZZZ
0

Sample Output

2

Source

2012 Asia Hangzhou Regional Contest

/* ***********************************************
Author        :CKboss
Created Time  :2015年08月17日 星期一 16时35分00秒
File Name     :HDOJ4460.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=2100;

int n,m;
int id=1;
map<string,int> msi;

int getID(string name)
{
	if(msi[name]==0) msi[name]=id++;
	return msi[name];
}

struct Edge
{
	int to,next,cost;
}edge[maxn*maxn];

int Adj[maxn],Size;
int du[maxn];

void init()
{
	id=1; msi.clear();
	memset(du,0,sizeof(du));
	memset(Adj,-1,sizeof(Adj)); Size=0;
}

void Add_Edge(int u,int v)
{
	edge[Size].to=v;
	edge[Size].cost=1;
	edge[Size].next=Adj[u];
	Adj[u]=Size++;
}

int dist[maxn],cq[maxn];
bool inq[maxn];

bool spfa(int st)
{
    memset(dist,63,sizeof(dist));
    memset(cq,0,sizeof(cq));
    memset(inq,false,sizeof(inq));
    dist[st]=0;
    queue<int> q;
    inq[st]=true;q.push(st); cq[st]=1;

    while(!q.empty())
    {
        int u=q.front();q.pop();

        for(int i=Adj[u];~i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dist[v]>dist[u]+edge[i].cost)
            {
                dist[v]=dist[u]+edge[i].cost;
                if(!inq[v])
                {
                    inq[v]=true;
                    cq[v]++;
                    if(cq[v]>=n+10) return false;
                    q.push(v);
                }
            }
        }
        inq[u]=false;
    }
    return true;
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);

	while(scanf("%d",&n)!=EOF&&n)
	{
		init();
		string name1,name2;
		for(int i=1;i<=n;i++)
		{
			cin>>name1;
		}
		scanf("%d",&m);
		for(int i=0;i<m;i++)
		{
			cin>>name1>>name2;
			int id1=getID(name1);
			int id2=getID(name2);
			Add_Edge(id1,id2); Add_Edge(id2,id1);
			du[id1]++; du[id2]++;
		}
		spfa(1);
		int st=1;
		for(int i=2;i<=n;i++)
		{
			if(dist[st]<dist[i]) st=i;
			else if(dist[st]==dist[i])
			{
				if(du[st]>du[i]) st=i;
			}
		}
		spfa(st);
		int ans=0;
		for(int i=1;i<=n;i++) ans=max(ans,dist[i]);
		if(ans==INF) ans=-1;
		cout<<ans<<endl;
	}

    return 0;
}
时间: 2024-08-07 00:15:39

HDOJ 4460 Friend Chains 图的最长路的相关文章

ZOJ3795 Grouping 强连通缩点+图的最长路

给出m条a年龄大于等于b的信息,要求可以比较的两个人不能放在同一组,问最少能分成几组. 由于是大于等于,所以原图可能构成强连通分量,意思就是有很多人年龄相同(想想也该知道,总共10w个人,肯定有很多人年龄重复= =!)将原图缩点后,对新图记忆化搜索求最长路. 如果不缩点,会RE... #include <iostream> #include<cstring> #include<cstdio> #include<string> #include<algo

POJ3592 Instantaneous Transference 强连通+最长路

题目链接: poj3592 题意: 给出一幅n X m的二维地图,每个格子可能是矿区,障碍,或者传送点 用不同的字符表示: 有一辆矿车从地图的左上角(0,0)出发,只能往右走或往下走,或者通过传送点  选择是否 传送到特定地点 采过的矿的格子 矿会消失;问这辆矿车最多能采多少矿 解题思路: 首先重新建图,将图中二维的顶点压缩成一维的顶点             (方便Tarjan算法) 每个顶点往右,下的顶点建边,传送点的格子往特定顶点建边(建边的两端不能有障碍) 得到一幅可能存在环的有向图;

[SDOI2010]所驼门王的宝藏 --tarjan缩点+最长路

[SDOI2010]所驼门王的宝藏 题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先知”的Alpaca L. Sotomon是这个家族的领袖,外人也称其为“所驼门王”.所驼门王毕生致力于维护家族的安定与和谐,他曾亲自率军粉碎河蟹帝国主义的野蛮侵略,为族人立下赫赫战功.所驼门王一生财宝无数,但因其生性节俭低调,他将财宝埋藏在自己设计的地下宫殿里,这也是今天Henry Curtis故事的起点.Henry是一个爱财如命的贪婪家伙,而又非常聪明,他费尽心机谋划了这次盗窃行动,

zoj3795 Grouping --- 强连通,求最长路

给定图,求把至少把图拆成几个集合能够使集合内的点没有直接或间接关系. 首先由题意可得图中可能含环,而环里面的点肯定是要拆开的. 缩点建图得DAG图,可以想象一下..把图从入度为零的点向下展开,位于同一层的点放在一个集合是没有关系的, 那么题目所求的问题就转化成求图中最长路的问题了. 这个题的实质和 这题 其实是一模一样的.. #include <iostream> #include <cstring> #include <string> #include <cst

HDU 3249 Test for job (有向无环图上的最长路,DP)

 解题思路: 求有向无环图上的最长路,简单的动态规划 #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <cmath> #define LL long long using namespace std; const int

POJ 3592--Instantaneous Transference【SCC缩点新建图 &amp;amp;&amp;amp; SPFA求最长路 &amp;amp;&amp;amp; 经典】

Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6177   Accepted: 1383 Description It was long ago when we played the game Red Alert. There is a magic function for the game objects which is called instantaneous

POJ 3592--Instantaneous Transference【SCC缩点新建图 &amp;&amp; SPFA求最长路 &amp;&amp; 经典】

Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6177   Accepted: 1383 Description It was long ago when we played the game Red Alert. There is a magic function for the game objects which is called instantaneous

分层图最短(长)路

1. 用途:用于求解一些有特定要求的最短路和最长路问题,如可以经过任意选择的某点几次,或者说任意选择某条路可以路径减半,或者说某条路可以逆行.....类似的看起来很动态的要求 看到这种题千万不要想不开去写dp,分层图是一个很好的思路. 但是多半这种题就有那么一点儿板 2.方法:对于每一种神奇的要求,我们建立要求个新图,并与原图上下平行.完全一致.在每一层图与图之间连边,相对应平行的点连0边,有关系的上下两层的点按照神奇要求连边(我语文不好 从第一层起点开始跑最短路到最后一层的终点,然后...就没

SDUTOJ 2498 AOE网上的关键路径(最长路)

AOE网上的关键路径 Time Limit: 1000MS Memory limit: 65536K 题目描述 一个无环的有向图称为无环图(Directed Acyclic Graph),简称DAG图. AOE(Activity On Edge)网:顾名思义,用边表示活动的网,当然它也是DAG.与AOV不同,活动都表示在了边上,如下图所示: 如上所示,共有11项活动(11条边),9个事件(9个顶点).整个工程只有一个开始点和一个完成点.即只有一个入度为零的点(源点)和只有一个出度为零的点(汇点)