zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    web基础要点记录
    前端一些干货
    正则表达式手册
    JQuery实现旋转轮播图
    JQuery模拟常见的拖拽验证
    electron应用以管理员权限启动
    原生JS模拟百度搜索关键字与跳转
    关于Application的使用
    Android事件分发机制(相关文章)
    (转)Activity的四种launchMode
  • 原文地址:https://www.cnblogs.com/gabo/p/2617630.html
Copyright © 2011-2022 走看看