POJ 3159 Candies 差分约束dij

分析:设每个人的糖果数量是a[i] 最终就是求a[n]-a[1]的最大值

然后给出m个关系 u,v,c 表示a[u]+c>=a[v] 就是a[v]-a[u]<=c

所以对于这种情况,按照u,v,c建单向边,一条从1到n的路径就是一个关于1和n的推广不等式a[n]-a[1]<=k(k为这条路的权)

所以找到所有不等式中最小k,就是求1到n的最短路,这就是差分约束

然后上代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=3e4+5;
const int INF=0x3f3f3f3f;
struct Edge{
   int v,w,next;
   bool operator<(const Edge &e)const{
      return w>e.w;
   } 
}edge[N*5];
int head[N],tot,n,m,d[N];
void add(int u,int v,int w){
   edge[tot].v=v;
   edge[tot].w=w;
   edge[tot].next=head[u];
   head[u]=tot++;
}
priority_queue<Edge>q;
bool vis[N];
int dij(int s,int t){
    for(int i=1;i<=n;++i)d[i]=INF,vis[i]=0;
    d[s]=0,q.push(Edge{s,0,0});
    while(!q.empty()){
       while(!q.empty()&&vis[q.top().v])q.pop();
       if(q.empty())break;
       int u=q.top().v;
       q.pop();
       vis[u]=1;
       for(int i=head[u];~i;i=edge[i].next){
          int v=edge[i].v;
          if(!vis[v]&&d[v]>d[u]+edge[i].w){
            d[v]=d[u]+edge[i].w;
            q.push(Edge{v,d[v],0});
          }
       } 
    }
    return d[t];
}
int main(){
    scanf("%d%d",&n,&m);
    memset(head,-1,sizeof(head)),tot=0;
    for(int i=1;i<=m;++i){
       int u,v,w;
       scanf("%d%d%d",&u,&v,&w);
       add(u,v,w);
    }
    printf("%d\n",dij(1,n));
    return 0;
}
View Code

 

posted @ 2016-03-25 17:41  shuguangzw  阅读(211)  评论(0编辑  收藏  举报