博弈论——取石子问题(转)
poj 2425 博弈 SG函数

poj 1201 第一道差分约束

scturtle posted @ 2010年9月08日 03:22 in algorithm , 2567 阅读

差分约束系统介绍 http://imlazy.ycool.com/post.1702305.html

设S[i]为数组Z在[0,i)上包含的数的个数,则对每一组a b c有,S[b+1]-S[a]>=c 即 S[a]-S[b+1]<=-c,建图时对应从S[b+1]到S[a]的一条权为-c的边.同时有隐含条件0<=S[i+1]-S[i]<=1即S[i+1]-S[i]<=1和S[i]-S[i+1]<=0,对应建图.

因为本题求的是可行解组中最小的,所以用最长路径求法.

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
#define maxn 50001
#define inf 0x3f3f3f3f
int n,m,tot;
struct Edge{int w,wt,next;}e[4*maxn];
int start[maxn];
int d[maxn];//单源距离

void add(int v,int w,int wt)
{
    e[tot].w=w;e[tot].wt=wt;
    e[tot].next=start[v];start[v]=tot++;
}

void spfa(int s)
{
    int i,v,N=0;
    deque<int> dq;
    for(v=0;v<n;v++) d[v]=inf;
    d[s]=0;
    dq.push_back(s);dq.push_back(n);
    while(!dq.empty())
    {
        v=dq.front();dq.pop_front();
        if(v==n)
        {if(N++>n) return;dq.push_back(n);}
        else
            for(i=start[v];i!=-1;i=e[i].next)
            {
                if(d[e[i].w]>d[v]+e[i].wt)
                {
                    d[e[i].w]=d[v]+e[i].wt;
                    dq.push_back(e[i].w);
                }
            }
    }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    freopen("out","w",stdout);
#endif
    int m,i,a,b,c,maxnum=0;
    scanf("%d",&m);
    tot=0;for(i=0;i<maxn;i++) start[i]=-1;
    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&a,&b,&c);
        add(b+1,a,-c);
        if(b+1>maxnum) maxnum=b+1;
    }
    for(i=0;i<maxnum;i++)
    {
        add(i,i+1,1);
        add(i+1,i,0);
    }
    n=maxnum+1;
    spfa(maxnum);
    printf("%d",d[maxnum]-d[0]);
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter