hdoj-1869 六度分离【最短路径--dijkstra&&spfa&&floyd】

来源:互联网 发布:华为网络认证多少钱 编辑:程序博客网 时间:2024/06/06 00:45

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1869

解题思路:

        转化成最短路径问题,如果两人认识,把两者之间距离看成1      如果任意两人之间隔着7个人及其以上 (即距离>7)   则不满足六度分离

 

spfa:

#include<cstdio>#include<cstring>#include<queue>#define INF 0x3f3f3f3f#define MAXN 100+10//点数 #define MAXM 400+10//边数 using namespace std;int n,m,top,vis[MAXN],dis[MAXN],head[MAXN];<span style="color:#009900;">struct node {    int from,to,val,next;};node edge[MAXM];void init()//初始化邻接表 {    top=0;//建表从零开始    memset(head,-1,sizeof(head));}void add(int u,int v,int w)//建立邻接表{//    edge[top].from=u;//    edge[top].to=v;//    edge[top].val=w;//    edge[top].next=head[u];//    head[u]=top++;    node E={u,v,w,head[u]};    edge[top]=E;    head[u]=top++;}</span>void spfa(int s)//s为源点{    int i;    queue<int>q;//存储每次入队的点    memset(vis,0,sizeof(vis));    memset(dis,INF,sizeof(dis));//存储源点 到这个点的最短路        vis[s]=1;//表示这个点是否在队列里面    dis[s]=0;    q.push(s);    while(!q.empty())    {        int u=q.front();        q.pop();        vis[u]=0;//该点之后还可能进入队列    消除标记          for( i=head[u];i!=-1;i=edge[i].next)//遍历以u为起点的 所有边        {            int v=edge[i].to;            if(dis[v]>dis[u]+edge[i].val)            {                dis[v]=dis[u]+edge[i].val;                if(!vis[v])                {                    q.push(v);                    vis[v]=1;                }            }        }    }}void getmap(){    int a,b;    while(m--)    {            scanf("%d%d",&a,&b);        add(a,b,1);        add(b,a,1);//无向图  既可由a->b,也可由b->a;     }}int main(){    int i,j;    while(~scanf("%d%d",&n,&m))    {        init();        getmap();        <span style="color:#ff0000;">int sign=1;</span>        for(i=0;i<n;i++)        {            spfa(i);            for(j=0;j<n;j++)            {                if(dis[j]>7)                {                    sign=0;                    break;//break 跳出循环  多数情况下与if else语句一起使用   对if语句不起作用  每次往外跳出一级                }            }           <span style="color:#ff0000;"> if(!sign)                 break;</span>        }        if(sign)             printf("Yes\n");        else             printf("No\n");    }    return 0;}

dijkstra:

#include<stdio.h>#include<string.h>#define INF 0x3f3f3f3f#define MAXN 100+10//using namespace std;int n,m,dis[MAXN],map[MAXN][MAXN],visit[MAXN];void dijkstra(int s){//int next=s;//一定要给next赋初值,否则会RE  int next;memset(visit,0,sizeof(visit));for(int i=0;i<n;i++)dis[i]=map[s][i];visit[s]=1;dis[s]=0;for(int i=1;i<n;i++){int min=INF;for(int u=0;u<n;u++){if(!visit[u]&&dis[u]<min){min=dis[u];next=u;}}visit[next]=1;   for(int u=0;u<n;u++)if(!visit[u]&&dis[u]>dis[next]+map[next][u])dis[u]=dis[next]+map[next][u];}}void getmap(){int a,b;for(int i=0;i<n;i++)for(int j=0;j<n;j++){if(i==j)map[i][j]=0;else map[i][j]=INF;}while(m--){scanf("%d%d",&a,&b);if(map[a][b]>1)map[a][b]=map[b][a]=1;}}int main(){int i,j;while(~scanf("%d%d",&n,&m)){int sign=1;getmap();for(i=0;i<n;i++){dijkstra(i);for(j=0;j<n;j++){if(dis[j]>7){sign=0;break;}}if(!sign)break;}if(sign)printf("Yes\n");else printf("No\n");}return 0;}



 

 

 

0 0