最短路径

来源:互联网 发布:淘宝有机证书编号 编辑:程序博客网 时间:2024/06/18 18:15

floyd

判断连通性

for(int k=1;k<=n;k++)        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)                mp[i][j]=mp[i][j]||(mp[i][k]&&mp[k][j]);                //if(mp[i][j]||(mp[i][k]&&mp[k][j]))                    mp[i][j]=true;

求最短路径

for(int k=1;k<=n;k++)        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)            if(mp[i][j]>mp[i][k]+mp[k][j])                mp[i][j]=mp[i][k]+mp[k][j]);

dijkstra

/*5 71 2 31 5 71 4 22 3 12 5 83 4 74 5 4*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=1e2+5;const int inf=0x7f7f7f7f;int maxn,n;//maxn为结点个数,n为边的条数int mp[N][N],dis[N];//dis即为最短路径void dijkstra(int v0){    //初始化,以v0为起点    bool s[maxn];//用于存储已经走过的结点    for(int i=1;i<=maxn;i++){        s[i]=false;        dis[i]=mp[v0][i];    }    s[v0]=true;    dis[v0]=0;    //    for(int i=2;i<=maxn;i++){//已经走过一个结点,所以从2开始        int mindis=inf,u;//u为下一步走的结点        for(int j=1;j<=maxn;j++){            if(!s[j]&&dis[j]<mindis){                u=j;mindis=dis[j];            }        }        s[u]=true;//该结点已经走过        //更新最短路径及距离        for(int j=1;j<=maxn;j++)            if(!s[j]&&mp[u][j]<inf) dis[j]=min(dis[j],dis[u]+mp[u][j]);            //mp[u][j]<inf可以防止溢出    }}int main(){    memset(mp,0x7f,sizeof(mp));    scanf("%d%d",&maxn,&n);    for(int i=0;i<n;i++)    {        int x,y,value;        scanf("%d%d%d",&x,&y,&value);        mp[x][y]=value;        mp[y][x]=value;//无向网图    }    int v;//原点    scanf("%d",&v);    dijkstra(v);    for(int i=1;i<=maxn;i++)        printf("%d  ",dis[i]);    return 0;}

用vector存图的dijkstra

#include<iostream>#include<algorithm>#include<cstring>#include<vector>using namespace std;const int inf=0x3f3f3f3f;struct node{    int ed,len;    node(){}    node(int ed,int len):ed(ed),len(len){}};vector<node>E[105];int main(){    ios::sync_with_stdio(false);    int n,m;    while(cin>>n>>m){        if(n==0&&m==0)            break;        for(int i=0;i<105;i++)            E[i].clear();        for(int i=1;i<=m;i++){            int a,b,c;            cin>>a>>b>>c;            E[a].push_back(node(b,c));            E[b].push_back(node(a,c));        }        bool s[105];        int dis[105];        memset(s,0,sizeof s);        memset(dis,0x3f,sizeof dis);        for(int i=0;i<E[1].size();i++)            dis[E[1][i].ed]=E[1][i].len;        dis[1]=0;        s[1]=true;        for(int i=2;i<=n;i++){            int u,mindis=inf;            for(int j=1;j<=n;j++){                if(!s[j]&&dis[j]<mindis){                    u=j;                    mindis=dis[j];                }            }            s[u]=true;            for(int j=0;j<E[u].size();j++)            if(!s[E[u][j].ed])                dis[E[u][j].ed]=min(dis[E[u][j].ed],dis[u]+E[u][j].len);        }        cout<<dis[n]<<endl;    }    return 0;}
#include<iostream>#include<algorithm>#include<cstring>using namespace std;const int inf=0x3f3f3f3f;struct node{    int ed,len,next;}e[20050];int p[105],num;void add(int st,int ed,int len){    e[num].ed=ed;    e[num].len=len;    e[num].next=p[st];    p[st]=num;    num++;}int main(){    ios::sync_with_stdio(false);    int n,m;    while(cin>>n>>m){        if(n==0&&m==0)            break;        memset(e,-1,sizeof e);        memset(p,-1,sizeof p);        num=0;        for(int i=1;i<=m;i++){            int a,b,c;            cin>>a>>b>>c;            add(a,b,c);            add(b,a,c);        }        bool s[105];        int dis[105];        memset(dis,0x3f,sizeof dis);        memset(s,0,sizeof s);        dis[1]=0;        for(int i=1;i<=n;i++){            int mindis=inf,u;            for(int j=1;j<=n;j++){                if(!s[j]&&dis[j]<mindis){                    u=j;                    mindis=dis[j];                }            }            s[u]=true;            for(int j=p[u];j!=-1;j=e[j].next){                if(!s[e[j].ed])                dis[e[j].ed]=min(dis[e[j].ed],dis[u]+e[j].len);            }        }        cout<<dis[n]<<endl;    }    return 0;}

vector存图可以减少内存开销
Struct node{
int en,len;
};
Vector E[num]; //num为点的个数。
其中E[u][j]表示结点u到结点j的路径

邻接表也可以减少内存开销
Struct node
{
int en,len,next;
}E[MAXM];
Int p[MAXN],num;
用结构体数组存下所有的边权,下一节点。
借助p数组标记,节点id,在E数组中的首位置。

初始化

Void init()
{
Memset(p,-1,sizeof(p));
Num=0;//num是存入E的第几条边
}

加边

Void add(int st,int en,int len)
{
E[num].en=en;
E[num].len=len;
E[num].next=p[st];//头插法
P[st]=num;
num++;
}
每次加边,可得以st为首节点,它邻接点存的位置p[st]。

遍历结点

For(i=p[u];i!=-1;i=E[i].next)
{
int v=E[i].en;
int length=E[i].len;
//i的初值为u点的第一个临界点在E[]数组的下标。然后i=E[i].next,递推找到下一个u的邻接点。知道为-1(p的初值)
}

原创粉丝点击