1201 Intervals SPFA

我自己的程序

#include<stdio.h>

#include<string.h>

const int E=50005;

const int V=50005;

const int INF=1<<25-1;

struct EDGE

{

    int link,val,next;

}edge[E*3];

int head[V],dist[V],q[E*3],e,rmin,rmax;

bool vis[V];

void addedge(int a,int b,int c)

{

    edge[e].link=b;

    edge[e].val=c;

    edge[e].next=head[a];

    head[a]=e++;

}

int relax(int u,int v,int c)

{

    if(dist[v]<dist[u]+c)//不能是<=,会死循环

    {

        dist[v]=dist[u]+c;

        return 1;

    }

    return 0;

}

void SPFA(int src)

{

    memset(vis,false,sizeof(vis));

    for(int i=rmin;i<=rmax;i++) dist[i]=-INF;

    int top=1;

    dist[src]=0;

    vis[src]=true;

    q[0]=src;

    while(top)

    {

        int u,v;

        u=q[--top];

        vis[u]=false;

        for(int i=head[u];i!=-1;i=edge[i].next)

        {

            v=edge[i].link;

            if(relax(u,v,edge[i].val)==1&&!vis[v])

            {

                 q[top++]=v;

                 vis[v]=true;

            }

        }

    }

}

int main()

{

    int n;

    while(scanf("%d",&n)!=EOF)

    {

        e=0;

        memset(head,-1,sizeof(head));

        rmin=1<<25-1; rmax=-1;

        for(int i=1;i<=n;i++)

        {

            int a,b,c;

            scanf("%d%d%d",&a,&b,&c);

            if(a<rmin)  rmin=a;

            if(b+1>rmax)  rmax=b+1;

            addedge(a,b+1,c);

        }

        for(int i=rmin;i<rmax;i++) addedge(i,i+1,0);

        for(int i=rmin;i<rmax;i++) addedge(i+1,i,-1);

        SPFA(rmin);

        printf("%d/n",dist[rmax]-dist[rmin]);

    }

    return 0;

}

这是网上一个程序,比我的要快不少
我还要改自己的程序
#include <iostream>
using namespace std;
const int max_n=50005;
struct Edge
{
    int to,weight,next;
} edges[max_n*4];
int edge_num=max_n;
void Add_Edge(int from,int to,int weight)
{
    edges[edge_num].to=to;
    edges[edge_num].weight=weight;
    edges[edge_num].next=edges[from].next;
    edges[from].next=edge_num;
    edge_num++;
}
int min_num[max_n];
int my_stack[max_n];
bool in_stack[max_n];
void Spfa(int num)
{
    memset(min_num,0,sizeof(min_num));
    memset(in_stack,1,sizeof(in_stack));
    for(int i=0; i<=num; i++) my_stack[i]=i;
    int stack_top=num;
    while(stack_top>=0)
    {
        int k=my_stack[stack_top--];
        int p=edges[k].next;
        while(p!=-1)
        {
            if(min_num[k]+edges[p].weight<min_num[edges[p].to])
            {
                min_num[edges[p].to]=min_num[k]+edges[p].weight;
                if(!in_stack[edges[p].to])
                {
                    my_stack[++stack_top]=edges[p].to;
                    in_stack[edges[p].to]=true;
                }
            }
            p=edges[p].next;
        }
        in_stack[k]=false;
    }
}
int main()
{
    int n,max_num=0,a,b,c;
    memset(edges,-1,sizeof(edges));
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        scanf("%d%d%d",&a,&b,&c);
        Add_Edge(b+1,a,-c);
        if(b+1>max_num) max_num=b+1;
    }
    for(int i=0; i<max_num; i++)
    {
        Add_Edge(i,i+1,1);
        Add_Edge(i+1,i,0);
    }
    Spfa(max_num);
    printf("%d/n",min_num[max_num]-min_num[0]);
    return 0;
}
诡异额
我把自己的程序用QUEUE来写,时间竟然快乐500多MS,逼近上面这个程序了
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int E=50005;
const int V=50005;
const int INF=1<<25-1;
struct EDGE
{
    int link,val,next;
}edge[E*3];
int head[V],dist[V],e,rmin,rmax;
bool vis[V];
void addedge(int a,int b,int c)
{
    edge[e].link=b;
    edge[e].val=c;
    edge[e].next=head[a];
    head[a]=e++;
}
int relax(int u,int v,int c)
{
    if(dist[v]<dist[u]+c)//不能是<=,会死循环
    {
        dist[v]=dist[u]+c;
        return 1;
    }
    return 0;
}
void SPFA(int src)
{
    memset(vis,false,sizeof(vis));
    for(int i=rmin;i<=rmax;i++) dist[i]=-INF;
    int top=1;
    dist[src]=0;
    vis[src]=true;
    queue<int> q;
    q.push(src);
    while(!q.empty())
    {
        int u,v;
        u=q.front();
        q.pop();
        vis[u]=false;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].link;
            if(relax(u,v,edge[i].val)==1&&!vis[v])
            {
                 q.push(v);
                 vis[v]=true;
            }
        }
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        e=0;
        memset(head,-1,sizeof(head));
        rmin=1<<25-1; rmax=-1;
        for(int i=1;i<=n;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            if(a<rmin)  rmin=a;
            if(b+1>rmax)  rmax=b+1;
            addedge(a,b+1,c);
        }
        for(int i=rmin;i<rmax;i++) addedge(i,i+1,0);
        for(int i=rmin;i<rmax;i++) addedge(i+1,i,-1);
        SPFA(rmin);
        printf("%d/n",dist[rmax]-dist[rmin]);
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值