最短路的几个板子题

Dijkstra:
题目链接:POJ - 1797
求解1~n的最短路 (双向边)
ac code:

#include
#include
#include
#include
using namespace std;
//#define inf 0xfffffff;
const int maxn=99999999;
int map_dis[1005][1005];
bool vis[1005];
int dis[1005];
int t,n,m;
int dijkstra(int s,int k){
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++)
    dis[i]=map_dis[s][i];
    dis[s]=0; vis[s]=true;
    for(int i=1;i<n;i++){
        int u,maxx=0;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&dis[j]>maxx){
                maxx=dis[j];
                u=j;
            }
        }
        if(u==1)break;
        vis[u]=true;
        for(int g=1;g<=n;g++){
            if(!vis[g]){
                dis[g]=max(dis[g],min(dis[u],map_dis[u][g]));
            }
        }
    }
    return dis[k];
}
int main()
{
    scanf("%d",&t);
    for(int i=1;i<=t;i++){
        memset(map_dis,0,sizeof(map_dis));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int b,e,v;
            scanf("%d%d%d",&b,&e,&v);
            //cout<
            map_dis[b][e]=map_dis[e][b]=v;
        }
        printf("Scenario #");
        printf("%d:\n",i);
        printf("%d\n",dijkstra(1,n));
        //if(i==t)
        cout<<endl;
    }
}

bellman:
题目链接:POJ - 3259
直接判断图内部是否有负环即可。
ac code;

//给一个无向图 并且 给一些 有向边 判断这个图中有没有 负环 如果有 时光可以倒流
//使用  bellman算法
#include
#include
#include
const int inf =0x3f3f3f3f;
const int maxn = 6000;
struct edge{
    int b,e,v;
}E[maxn];
int dis [550];
bool bellman(int s,int n,int nedge)
{
    for(int i=1;i<=n;i++){
        dis[i]=(i==s?0:inf);
    }
    for(int i=1;i<n;i++){
        for(int j=1;j<=nedge;j++){
            if(dis[E[j].b]!=inf&&dis[E[j].e]>dis[E[j].b]+E[j].v)
            dis[E[j].e]=dis[E[j].b]+E[j].v;
        }
    }
    for(int g=1;g<=nedge;g++){
        if(dis[E[g].e]>dis[E[g].b]+E[g].v){
            return true;
        }
    }
    return false;
}
int main()
{
    int t,n,m,w,nnum;
    scanf("%d",&t);
    while(t--){
        nnum=0;
        scanf("%d%d%d",&n,&m,&w);
        for(int i=1;i<=m;i++){
            int bb,ee,vv;
            scanf("%d%d%d",&bb,&ee,&vv);
            E[++nnum].b=bb;E[nnum].e=ee;
            E[nnum].v=vv;
            E[++nnum].b=ee;E[nnum].e=bb;
            E[nnum].v=vv;
        }
        for(int j=1;j<=w;j++){
            int bb,ee,vv;
            scanf("%d%d%d",&bb,&ee,&vv);
            E[++nnum].b=bb;E[nnum].e=ee;
            E[nnum].v=-vv;
        }
        if(bellman(1,n,nnum))printf("YES\n");
        else printf("NO\n");
    }
}

dijkstra + 优先队列优化:
题目链接:POJ - 1502
ac code:

#include
#include
#include
#include
#include
using namespace std;
const int maxn=110;
const int maxv=10050;
const int inf=0x3f3f3f3f;
int vis[maxn];
int dis[maxn];
struct edge{
    int u,v,w,next;
}e[maxv];
struct node{
    int dist,num;
    friend bool operator < (node a,node b){
        return a.dist>b.dist;
    }
}p[maxn];
int head[maxn];
void init(){
    memset(vis,0,sizeof(vis));
    memset(dis,inf,sizeof(dis));
    memset(head,-1,sizeof(head));
}
void dijkstra(int b){
    priority_queue<node>q;
    vis[b]=1;
    dis[b]=0;
    node now,temp;
    now.dist=dis[b];
    now.num=b;
    q.push(now);
    while(!q.empty()){
        now=q.top();
        q.pop();
        vis[now.num]=0;
        for(int i=head[now.num];i!=-1;i=e[i].next){
            if(dis[e[i].v]>dis[now.num]+e[i].w){
                dis[e[i].v]=dis[now.num]+e[i].w;
                if(!vis[e[i].v]){
                    vis[e[i].v]=1;
                    temp.dist = dis[e[i].v];
                    temp.num = e[i].v;
                    q.push(temp);
                }
            }
        }
    }
}
int main()
{
    int n;
    int cnt=0;
    scanf("%d",&n);
    init();
    for(int i=1;i<n;i++){
        for(int j=1;j<=i;j++){
            char s[10];
            scanf("%s",s);
            if(s[0]!='x'){
                int temp=0;
                int slen=strlen(s);
                for(int k=0;k<slen;k++){
                    temp=(temp*10+(s[k]-'0'));
                }
                e[++cnt].u=i+1;e[cnt].v=j;
                e[cnt].w=temp;e[cnt].next=head[i+1];
                head[i+1]=cnt;
                e[++cnt].u=j;e[cnt].v=i+1;
                e[cnt].w=temp;e[cnt].next=head[j];
                head[j]=cnt;
            }
        }
    }
    dijkstra(1);
    int maxx=0;
    for(int i=1;i<=n;i++){
        //cout<
        maxx=max(maxx,dis[i]);
    }
    printf("%d\n",maxx);

}

spfa判断负环:
题目链接:POJ - 2240
ac code :

#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=50;
const int maxv=2500;
int vis[maxn];
int visitcnt[maxn];
double dis[maxn];
struct edge {
    int u,v,next;
    double w;
}e[maxv];
struct  node{
    char s[50];
    int num;
}p[maxn];
int head[maxn];
void init(){
    memset(vis,0,sizeof(vis));
    memset(dis,0.0,sizeof(dis));
    memset(visitcnt,0,sizeof(visitcnt));
}
bool spfa(int n,int b){
    queue<int>q;
    vis[b]=1;
    dis[b]=1;
    q.push(b);
    while(!q.empty()){
        int now=q.front();
        visitcnt[now]++;
        if(visitcnt[now]>n)return true;
        q.pop();
        vis[now]=0;
        for(int i=head[now];i!=-1;i=e[i].next){
            if(dis[e[i].v]<dis[now]*e[i].w){
                dis[e[i].v]=dis[now]*e[i].w;
                if(!vis[e[i].v]){
                    q.push(e[i].v);
                    vis[e[i].v]=1;
                }
            }
        }
    }
    return false;
}
int main()
{
    int n,m,tt=0;
    while(scanf("%d",&n)&&n){
        memset(head,-1,sizeof(head));
        init();
        int cnt=0;
        for(int i=1;i<=n;i++){
            scanf("%s",p[i].s);
            p[i].num=i;
        }
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            int u,v;
            double w;
            char ss[50];
            scanf("%s",ss);
            for(int j=1;j<=n;j++){
                if(strcmp(ss,p[j].s)==0){
                    u=p[j].num;
                    break;
                }
            }
            scanf("%lf",&w);
            scanf("%s",ss);
            for(int j=1;j<=n;j++){
                if(strcmp(ss,p[j].s)==0){
                    v=p[j].num;
                    break;
                }
            }
            //cout<
            e[++cnt].u=u;e[cnt].v=v;
            e[cnt].w=w;e[cnt].next=head[u];
            head[u]=cnt;
        }
        bool flag=spfa(n,1);
        printf("Case %d: ",++tt);
        if(flag){
            printf("Yes\n");
        }
        else{
            printf("No\n");
        }
    }
}

你可能感兴趣的:(最短路,最短路)