zoukankan      html  css  js  c++  java
  • hdoj 1869 六度分离【最短路径求两两边之间最长边】

    六度分离

    Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5443    Accepted Submission(s): 2208


    Problem Description
    1967年,美国著名的社会学家斯坦利·米尔格兰姆提出了一个名为“小世界现象(small world phenomenon)”的著名假说,大意是说,任何2个素不相识的人中间最多只隔着6个人,即只用6个人就可以将他们联系在一起,因此他的理论也被称为“六度分离”理论(six degrees of separation)。虽然米尔格兰姆的理论屡屡应验,一直也有很多社会学家对其兴趣浓厚,但是在30多年的时间里,它从来就没有得到过严谨的证明,只是一种带有传奇色彩的假说而已。

    Lele对这个理论相当有兴趣,于是,他在HDU里对N个人展开了调查。他已经得到了他们之间的相识关系,现在就请你帮他验证一下“六度分离”是否成立吧。
     

     

    Input
    本题目包含多组测试,请处理到文件结束。
    对于每组测试,第一行包含两个整数N,M(0<N<100,0<M<200),分别代表HDU里的人数(这些人分别编成0~N-1号),以及他们之间的关系。
    接下来有M行,每行两个整数A,B(0<=A,B<N)表示HDU里编号为A和编号B的人互相认识。
    除了这M组关系,其他任意两人之间均不相识。
     

     

    Output
    对于每组测试,如果数据符合“六度分离”理论就在一行里输出"Yes",否则输出"No"。
     

     

    Sample Input
    8 7
    0 1
    1 2
    2 3
    3 4
    4 5
    5 6
    6 7
    8 8
    0 1
    1 2
    2 3
    3 4
    4 5
    5 6
    6 7
    7 0
     

     

    Sample Output
    Yes
    Yes
    题意:任意两个人之间最多通过六个人连接叫做六度分离
    思路:让任意两个人之间的最短路小于7即可
    dijkstra算法:
    #include<stdio.h>
    #include<string.h>
    #define MAX 1000
    #define INF 0x3f3f3f
    int map[MAX][MAX],vis[MAX];
    int low[MAX];
    int n,m;
    int ok;
    void prime(int y,int x)
    {
    	int i,j,next;
    	int min,mincost=0;
    	memset(vis,0,sizeof(vis));
    	for(i=0;i<n;i++)
    	{
    		low[i]=map[y][i];
    	}
    	vis[y]=1;
    	for(i=0;i<n-1;i++)
    	{
    		min=INF;
    		for(j=0;j<n;j++)
    		{
    			if(!vis[j]&&min>low[j])
    			{
    				min=low[j];
    			    next=j;
    			}
    	    }
    	    vis[next]=1;
    	    for(j=0;j<n;j++)
    	    {
    	    	if(!vis[j]&&low[j]>map[next][j]+low[next])
    	    	low[j]=map[next][j]+low[next];
    	    }
    	} 
    	if(low[x]==INF||low[x]-1>6)
    	{
    		ok=0;
    		printf("No
    ");
    	}
    }
    int main()
    {
    	int j,i,s,t,l;
    	int a,b;
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{
    		for(i=0;i<n;i++)
    		{
    			for(j=0;j<n;j++)
    			{
    				if(i==j)
    				map[i][j]=map[j][i]=0;
    				else
    				map[i][j]=INF;
    			}
    		}
    		for(i=0;i<m;i++)
    		{
    			scanf("%d%d",&a,&b);
    			map[a][b]=map[b][a]=1;
    		}
    		ok=1;
    		for(j=0;j<n;j++)
    		{
    			for(i=0;i<n;i++)
    		    {
    			    prime(j,i);
    			    if(ok==0)
    			    break;
    		    }
    		    if(ok==0)
    		    break;
    		}
    		if(ok)
    		printf("Yes
    ");
    	}
    	return 0;
    }
    
    

     spfa:

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #define MAX 2000
    #define INF 0x3f3f3f
    using namespace std;
    int n,m,ans;
    int beg,en;
    int dis[MAX],vis[MAX];
    int head[MAX];
    struct node
    {
    	int u,v,w;
    	int next;
    }edge[MAX];
    void init()
    {
    	ans=0;
    	memset(head,-1,sizeof(head));
    }
    void add(int u,int v,int w)
    {
    	edge[ans].u=u;
    	edge[ans].v=v;
    	edge[ans].w=w;
    	edge[ans].next=head[u];
    	head[u]=ans++;
    }
    void getmap()
    {
    	int a,b;
    	while(m--)
    	{
    		scanf("%d%d",&a,&b);
    		add(a,b,1);
    		add(b,a,1);
    	}
    }
    void spfa(int sx)
    {
        int i,j;
        queue<int>q;
        memset(vis,0,sizeof(vis));
        for(i=0;i<=n;i++)
            dis[i]=INF;
        vis[sx]=1;
        dis[sx]=0;
        q.push(sx);
        while(!q.empty())
        {
        	int u=q.front();
        	q.pop();
        	vis[u]=0;
        	for(i=head[u];i!=-1;i=edge[i].next)
        	{
        		int top=edge[i].v;
        		if(dis[top]>dis[u]+edge[i].w)
        		{
        			dis[top]=dis[u]+edge[i].w;
        			if(!vis[top])
        			{
        				vis[top]=1;
        				q.push(top);
    				}
    			}
    		}
    	}
    }
    void solve()
    {
    	int i,j;
    	int ok=0;
    	for(i=0;i<n;i++)
    	{
    		spfa(i);
    		for(j=0;j<n;j++)
    		{
    			if(dis[j]>7)
    			{
    				ok=1;
    				break;
    			}	
    		}
    		if(ok)
    		break;
    	}
    	if(ok)
    	printf("No
    ");
    	else
    	printf("Yes
    ");
    }
    int main()
    {
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{
    		init();
    		getmap();
    		solve();
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Java 递归算法,遍历文件夹下的所有文件。
    基于appium的移动端自动化测试,密码键盘无法识别问题
    第一个脚印
    最简单ajax,$.post()用法
    关于图片title与alt
    iframe loading 效果
    iframe 跨域的高度自适应
    练习卷动式新闻广告牌
    JS学习笔记《数值与字符串相加篇》
    解决FLASH的层级问题
  • 原文地址:https://www.cnblogs.com/tonghao/p/4671371.html
Copyright © 2011-2022 走看看