邮递员送信(rms模拟3-4)* * (dijkstra)

来源:互联网 发布:ubuntu emuleweb 编辑:程序博客网 时间:2024/06/06 02:40

题目描述

有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有M条道路,通过每条道路需要一定的时间。这个邮递员每次只能带一样东西。求送完这N-1样东西并且最终回到邮局最少需要多少时间。
输入输出格式
输入格式:

第一行包括两个整数N和M。

第2到第M+1行,每行三个数字U、V、W,表示从A到B有一条需要W时间的道路。 满足1<=U,V<=N,1<=W<=10000,输入保证任意两点都能互相到达。

数据规模

对于30%的数据,有1≤N≤200;

对于100%的数据,有1≤N≤1000,1≤M≤100000。

输出格式

输出仅一行,包含一个整数,为最少需要的时间。

输入输出样例
输入样例#1:

5 10
2 3 5
1 5 5
3 5 6
1 2 8
1 3 8
5 3 4
4 1 8
4 5 3
3 5 6
5 4 2

输出样例#1:

83
题解
正向做一遍单源最短路,再反向做一遍
30%:floyd — O(n^3)
70%:spfa —O ( 2kE k一般<=2 ) 邻接矩阵可ac 数据太坑了orz
100%:dijsktra —O(2nlog2n)

spfa适用于稀疏图
dijksra适用于稠密图

代码 dijkstra

#include<bits/stdc++.h>#define F( i,a,b ) for( int i=( a );i<=( b );i++ )#define F_2( i,a,b ) for( int i=( a );i>=( b );i++ )#define N 1001#define M 100001#define P 1000000007#define LL long long#define oo 10000007using namespace std;int read(){    int f=1,s=0;    char ch=getchar();    while( ch<'0' || ch>'9' ) { if( ch=='-' ) f=-1; ch=getchar(); }    while( ch>='0' && ch<='9' ) { s=( s<<1 )+( s<<3 )+ch-'0'; ch=getchar(); }    return f*s;}int m,n,k;int tot,ans,cnt;int x[M],y[M],z[M];int head[N],vis[N],d[N];struct edge{    int nxt,w,to;}e[M];struct node{    int num,w;};priority_queue<node> q;bool operator<( node a,node b ){    return a.w>b.w;}void addedge( int cu,int cv,int cw ){    cnt++;    e[cnt].to=cv;    e[cnt].nxt=head[cu];    e[cnt].w=cw;    head[cu]=cnt;}void dijkstra(){    q.push( ( node ){1,0} );    while( !q.empty() )    {        int u=q.top().num;              q.pop();        if( !vis[u] )        {            for( int i=head[u];i;i=e[i].nxt )            {                int v=e[i].to;                int w=e[i].w;                if( d[u]+w<d[v] )                {                    d[v]=d[u]+w;                    q.push( ( node ){v,d[v]} );                }            }        }         vis[u]=1;    }}int main(){    n=read();    m=read();    F( i,1,m )    {        x[i]=read();        y[i]=read();        z[i]=read();    }    F( i,1,m )        addedge( x[i],y[i],z[i] );    fill( d+1,d+n+1,oo );    d[1]=0;    dijkstra();    F( i,1,n )        ans+=d[i];    cnt=0;    memset( e,0,sizeof( e ) );    memset( head,0,sizeof( head ) );    F( i,1,m )        addedge( y[i],x[i],z[i] );    memset( vis,0,sizeof( vis ) );    fill( d+1,d+n+1,oo );    d[1]=0;    dijkstra();    F( i,1,n )        ans+=d[i];    cout<<ans<<endl;    return 0;}

spfa

#include<bits/stdc++.h>#define F( i,a,b ) for( int i=(a);i<=(b);i++ )#define N 100001#define M 1001#define oo 100007using namespace std;int read(){    int f=1,s=0;    char ch=getchar();    while( ch<'0' || ch>'9' ) { if( ch=='-' ) f=-1; ch=getchar(); }    while( ch>='0' && ch<='9' ) { s=( s<<1 )+( s<<3 )+ch-'0'; ch=getchar(); }    return f*s;}int m,n;int x[N],y[N],z[N];int head[N],vis[N],d[N];int cnt,ans;struct edge{    int nxt,w,to;}e[N];void addedge( int cu,int cv,int cw ){    cnt++;    e[cnt].to=cv;    e[cnt].nxt=head[cu];    e[cnt].w=cw;    head[cu]=cnt;}void spfa( int u ){    vis[u]=1;    for( int i=head[u];i;i=e[i].nxt )    {        int v=e[i].to;        int w=e[i].w;        if( d[u]+w<d[v] )        {            d[v]=d[u]+w;            if( !vis[v] )                spfa( v );        }        }    vis[u]=0;}int main(){    n=read();    m=read();    F( i,1,m )    {        x[i]=read();        y[i]=read();        z[i]=read();    }    F( i,1,m )        addedge( x[i],y[i],z[i] );    fill( d+1,d+n+1,oo );    d[1]=0;    spfa( 1 );    F( i,1,n )        ans+=d[i];    memset( vis,0,sizeof(vis) );    memset( e,0,sizeof( e ) );    memset( head,0,sizeof( head ) );    F( i,1,m )      {        addedge( y[i],x[i],z[i] );      }    fill( d+1,d+n+1,oo );    d[1]=0;    spfa( 1 );    F( i,1,n )        ans+=d[i];    cout<<ans<<endl;    return 0;}