poj 3159 Candies 差分约束

poj 3159 Candies 差分约束
//poj 3159 Candies



//差分约束

//不了解差分约束的可以看看这个

//http://hi.baidu.com/qinning199/item/65d270215bb365182a0f1c07

//这题是我的第一题差分约束



//题意:

//有n个孩子分糖果,m个孩子的要求,没个要求都有三个数A,B,c

//表示A孩子要求B孩子拿到的糖果不能超过自己 c个



//思路:

//其实主要就是找出类似最短路中的三角不等式d[v]<=d[u]+w[u,v]

//找到这关系后,就可以根据最短路来求解了,求出来的dis数组就是满足每

//个孩子要求的前提下,分配给每个孩子的糖果数

//这题边太多 卡用队列的spfa,用优先队列优化的dijsktra就可以500多ms  ac



#define comein freopen("in.txt", "r", stdin);

#include <stdio.h>

#include <string.h>

#include <queue>

using namespace std;



#define INF 1<<30

#define N 30005



struct EDGE

{

    int to, dis, next;

}edge[150005];



struct S

{

    int pos, dis;

    S(int pos, int d)

    {

        this->pos = pos;

        this->dis = d;

    }

    S(){}

    bool operator < (const S &other)const

    {

        return this->dis > other.dis;

    }

};



int tot;

int head[N], dis[N];

bool vis[N];



void add_edge(int from, int to, int d)

{

    edge[++tot].to = to;

    edge[tot].dis = d;

    edge[tot].next = head[from];

    head[from] = tot;

}



void dijsktra(int n_kid)

{

    priority_queue<S> que;

    dis[1] = 0;

    int now = 1;

    while(1)

    {

        vis[now] = true;

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

        {

            int to = edge[i].to;

            if(vis[to] == false && (dis[to] == -1 ||dis[to] - dis[now] > edge[i].dis))

            {

                dis[to] = dis[now] + edge[i].dis;

                que.push(S(to, dis[to]));

            }

        }

        int tmp = now;

        while(!que.empty())

        {

            S ttt = que.top();

            que.pop();

            if(vis[ttt.pos] == false)

            {

                now = ttt.pos;

                break;

            }

        }

        if(tmp == now)

            break;

    }

}



//void spfa(int n_kid)    //TLE

//{

//    queue<int>que;

//    dis[1] = 0;

//    que.push(1);

//    vis[1] = true;

//    while(!que.empty())

//    {

//        int now = que.front();

//        que.pop();

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

//        {

//            int to = edge[i].to;

//            if(dis[to] == -1 || dis[to] - dis[now] >= edge[i].dis)

//            {

//                dis[to] = dis[now] + edge[i].dis;

//                if(vis[to] == false)

//                {

//                    que.push(to);

//                    vis[to] = true;

//                }

//            }

//        }

//        vis[now] = false;

//    }

//}



int main()

{

    comein

    int n_kid, m;

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

    {

        tot = 0;

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

        {

            head[i] = -1;

            vis[i] = false;

            dis[i] = -1;

        }

        for(int i = 0; i < m; ++i)

        {

            int from, to, d;

            //x1孩子 认为 x2 孩子的糖果不能超过自己c个

            //x1 - x2 <= c ->  dis[to] - dis[from] <= d

            //那如果 dis[to] - dis[from] >= d的话我们就要维护

            //让他保持dis[to] - dis[from] <= d 得到的就是正确的解

            scanf("%d%d%d", &from, &to, &d);

            add_edge(from, to, d);

        }

//        spfa(n_kid);    //TLE

        dijsktra(n_kid);

        printf("%d\n", dis[n_kid]);

    }

    return 0;

}

 

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