zoukankan      html  css  js  c++  java
  • 最短路的一些理解

    dij是单源的,只是从一个顶点出发到其它点的最短距离,并且它的全值都是正的,不能够有负值;

    Bellman-ford 也是单源的,但是他能够完成负权值的图,这是dij无法达到的,并且能够判断是否存在负环,经过修改可以求最长路;
    SPFA是在Bellman-ford上优化的,所以跟快;

    floyd算法可以求出任意两点的最短路,索然dij对每个点一次for也能求出,但是复杂度O(n^3)或O(n^2+ne),一次floyd也是O(n^3),
    但是floyd更加易懂,简洁;floyd允许带负值的边,但不能有回路(环);floyd很灵活,可以多种变换;

    (个人的理解 不是很深,只懂一点)

      1 poj3268
      2 很多牛,要到x这个点,来回多少时间;
      3 正向,反向2次SPFA,2个值相加,然后取最大;
      4 #include<STDIO.H>
      5 #include<string.h>
      6 #include<queue>
      7 #define INF 999999999
      8 using namespace std;
      9 struct node
     10 {
     11     int v;
     12     int val;
     13     int next;
     14 }edge1[100003],edge2[100003];
     15 int head1[1003],dis1[1003],head2[1003],dis2[1003];
     16 int n,m,t,index1,index2;
     17 void add1(int x,int y,int z)
     18 {
     19     int i,j;
     20     edge1[index1].v=y;
     21     edge1[index1].val=z;
     22     edge1[index1].next=head1[x];
     23     head1[x]=index1++;
     24 }
     25 void add2(int x,int y,int z)
     26 {
     27     int i,j;
     28     edge2[index2].v=y;
     29     edge2[index2].val=z;
     30     edge2[index2].next=head2[x];
     31     head2[x]=index2++;
     32 }
     33 void SPFA1(int u)
     34 {
     35     int vis[1003],i,j;
     36     memset(vis,0,sizeof(vis));
     37     queue<int>q;
     38     for(i=1;i<=n;i++)
     39         dis1[i]=INF;
     40     dis1[u]=0;
     41     vis[u]=1;
     42     q.push(u);
     43     while(!q.empty())
     44     {
     45         int v=q.front();
     46         q.pop();
     47         vis[v]=0;
     48         for(i=head1[v];i!=-1;i=edge1[i].next)
     49         {
     50             int tmp=edge1[i].v;
     51             if(dis1[tmp]>dis1[v]+edge1[i].val)
     52             {
     53                 dis1[tmp]=dis1[v]+edge1[i].val;
     54                 if(!vis[tmp])
     55                 {
     56                     q.push(tmp);
     57                     vis[tmp]=1;
     58                 }
     59             }
     60         }
     61     }
     62 }
     63 void SPFA2(int u)
     64 {
     65     int vis[1003],i,j;
     66     memset(vis,0,sizeof(vis));
     67     queue<int>q;
     68     for(i=1;i<=n;i++)
     69         dis2[i]=INF;
     70     dis2[u]=0;
     71     vis[u]=1;
     72     q.push(u);
     73     while(!q.empty())
     74     {
     75         int v=q.front();
     76         q.pop();
     77         vis[v]=0;
     78         for(i=head2[v];i!=-1;i=edge2[i].next)
     79         {
     80             int tmp=edge2[i].v;
     81             if(dis2[tmp]>dis2[v]+edge2[i].val)
     82             {
     83                 dis2[tmp]=dis2[v]+edge2[i].val;
     84                 if(!vis[tmp])
     85                 {
     86                     q.push(tmp);
     87                     vis[tmp]=1;
     88                 }
     89             }
     90         }
     91     }
     92 }
     93 int main()
     94 {
     95     int i,j;
     96     while(scanf("%d%d%d",&n,&m,&t)!=EOF)
     97     {
     98         index1=index2=1;
     99         memset(dis1,0,sizeof(dis1));
    100         memset(head1,-1,sizeof(head1));
    101         memset(dis2,0,sizeof(dis2));
    102         memset(head2,-1,sizeof(head2));
    103         for(i=0;i<m;i++)
    104         {
    105             int x,y,z;
    106             scanf("%d%d%d",&x,&y,&z);
    107             add1(x,y,z);
    108             add2(y,x,z);
    109         }
    110 
    111         SPFA1(t);
    112 
    113         /*for(i=1;i<=n;i++)
    114         printf("%d ",dis1[i]);
    115         printf("
    ");*/
    116 
    117         SPFA2(t);
    118 
    119         /*for(i=1;i<=n;i++)
    120         printf("%d ",dis2[i]);printf("
    ");*/
    121 
    122         int max=0;
    123         for(i=1;i<=n;i++)
    124         {
    125             if(max<dis2[i]+dis1[i])
    126                 max=dis2[i]+dis1[i];
    127         }
    128         printf("%d
    ",max);
    129     }
    130 }
    /*poj2570
    floyd算法来找到所有可能的路径;
    用二进制26位表示路径;
    0000000000.......111,这个表示abc;
    floyd时 map[i][j]|=map[i][k]&map[k][j];
    |表示有新的路径 那么就合并路径,&表示存在这个路;
    最后遍历26个字母即可;*/
    //poj2570
    #include<stdio.h>
    #include<string.h>
    int map[203][203];
    int n;
    int main()
    {
        int i,j,l,x,y;
        while(scanf("%d",&n)!=EOF)
        {
            if(!n)break;
            memset(map,0,sizeof(map));
            char s[50];
            while(1)
            {
                x,y;
                scanf("%d %d",&x,&y);
                if(x==0&&y==0)
                    break;
                scanf("%s",s);
                l=strlen(s);
                for(i=0;i<l;i++)
                {
                    map[x][y]|=1<<(s[i]-'a');
                }
            }
            //floyd
            for(i=1;i<=n;i++)
                for(j=1;j<=n;j++)
                    for(int k=1;k<=n;k++)
                    {
                        map[j][k]|=(map[j][i] & map[i][k]);
                    }
            char ii;
            while(1)
            {
                scanf("%d %d",&x,&y);
                if(x==0&&y==0)break;
                for(ii='a';ii<='z';ii++)
                {
                    if(map[x][y] & (1<<(ii-'a')))
                    {
                        printf("%c",ii);
                    }
                    
                }
                if(!map[x][y])
                {
                    printf("-");
                }
                putchar('
    ');
            }
            putchar('
    ');
        }
    }
    
    
    
    //poj2263
    /*floyd来求解最大能够载重;
    应为A->C可以有2种情况 A->B,B->C或者A->C,要得到A->C这条道路最大的载重量,由于A,B,C这三条路的载重不同,
    所以要找出A->B,B->C的最小载重,因为如果取大的,另外一条就不能了,然后再取直接到和间接到的最大值,
    此时可以用floyd来解决问题;*/
    #include<stdio.h>
    #include<string.h>
    #define INF 99999999
    int map[205][205];
    int num;//统计city
    int n,m;
    char s[20],e[20];
    char in1[30],in2[30];
    char city[205][50];
    int max(int x,int y)
    {
        return x>y?x:y;
    }
    int min(int x,int y)
    {
        return x<y?x:y;
    }
    int inset(char a[])
    {
        int i,j;
        for(i=0;i<num;i++)
        {
            if(strcmp(city[i],a)==0)
            {
                return i;
            }
        }
        num++;
        strcpy(city[i],a);
        return i;
    }
    int floyd()
    {
        int i,j,k;
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
                for(k=0;k<n;k++)
                {
                    map[j][k]=max(map[j][k],min(map[j][i],map[i][k]));
                }
        int x,y;
        x=inset(s);
        y=inset(e);
        return map[x][y];
    }
    int main()
    {
        int i,j;
        int ff=0;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            if(!n&&!m)break;
            memset(map,0,sizeof(map));
            num=0;
            for(i=0;i<=n;i++)
                map[i][i]=INF;
            for(i=0;i<m;i++)
            {
                int z;
                scanf("%s %s %d",in1,in2,&z);
                int x,y;
                x=inset(in1);
                y=inset(in2);
                map[x][y]=map[y][x]=z;
            }
            scanf("%s %s",s,e);
            int ans=floyd();
            printf("Scenario #%d
    ",++ff);
            printf("%d tons
    ",ans);
            printf("
    ");
        }
    }
  • 相关阅读:
    JVM 类加载过程
    JVM调优总结 -Xms
    JVM 内存模型
    git克隆远程项目并创建本地对应分支
    内存泄漏 和 内存溢出
    weblogic 乱码
    tomcat 、NIO、netty 本质
    Anything is possible if you have got enough nerve.
    maven build 的时候,卡死在Downloading metadata的解决方法
    TimeUnit
  • 原文地址:https://www.cnblogs.com/sweat123/p/4502992.html
Copyright © 2011-2022 走看看