约分差束1

又好久没写博客了,囧。

这回概率期中估计要成为我上大学以来最烂的成绩了,毕竟上概率课补睡眠时间,考试前几天并无心思抱佛脚,还在撸着acm。

约分差束是一种最短路的衍生物。

这里讲的非常好。点击打开链接

hdu 1384

#include <cstdio>
#include <stdio.h>
#include <cstring>
#include <map>
#include <algorithm>
#include <queue>
#define INF 0x3f3f3f3f
#define SIZE 50010
using namespace std;

int v[4*SIZE],cnt=1,MAX=0,MIN=INF;

struct ee{
int to,w,next,be;
}eage[4*SIZE];

void init()
{
   memset(v,-1,sizeof(v));
   MAX=0,MIN=INF;
   cnt=1;
}

void addeage(int a,int b,int c)
{
    eage[cnt].to=b;
    eage[cnt].be=a;
    eage[cnt].w=c;
    eage[cnt].next=v[a];
    v[a]=cnt;
    cnt++;
}

void spfa()
{
    queue<int>myqueue;
    bool instack[4*SIZE];
    memset(instack,false,sizeof(instack));
    int d[4*SIZE];
    memset(d,-INF,sizeof(d));
    d[MIN]=0;
    instack[MIN]=true;
    myqueue.push(MIN);
    while(!myqueue.empty())
    {
        int q=myqueue.front();
        myqueue.pop();
        instack[q]=false;
        for(int i=v[q];i!=-1;i=eage[i].next)
        {
             if(d[eage[i].to]-d[eage[i].be]<eage[i].w)
             {
             d[eage[i].to]=d[eage[i].be]+eage[i].w;
             if(!instack[eage[i].to])
             {
                myqueue.push(eage[i].to);
                instack[eage[i].to]=true;
             }
             }
        }
    }
     printf("%d\n",d[MAX]);
}


int main ()
{
    //freopen("d:\\in.txt","r",stdin);
    int n;
    while(~scanf("%d",&n))
    {
        init();
        for(int i=1;i<=n;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            MAX=max(MAX,b+1);
            MIN=min(MIN,a);
            addeage(a,b+1,c);
        }
        for(int i=MIN;i<MAX;i++)
        {
            addeage(i+1,i,-1);
            addeage(i,i+1,0);
        }
        spfa();
    }
    return 0;
}

这道题虽说入门题,但还是有比较多的地方值得注意。

菜鸟没办法。。。。。。。。。。

1.区间可能会重叠6~8 8~10

所以加入边的时候要变为6~9 8~11

2.有环所以每个点不一定只入队一次,可以多次,所以时间复杂度还是比较高的。

3.题目本身还有两个隐含条件。0<=ai-ai+1<=1。

你可能感兴趣的:(约分差束1)