hdu 1531(差分约束)

来源:互联网 发布:手机调音量软件 编辑:程序博客网 时间:2024/05/17 02:08

传送门
题解:
转为前缀处理。
如果大于,s[u+len]-s[u-1]≥k+1,s[u-1]≤s[u+len]-k-1,连边(u+len,u-1,-k-1)
如果小于,s[u+len]-s[u-1]≤k-1,s[u+len]≤s[u-1]+k-1,连边(u-1,u+len,k-1)
所有点入队,跑SPFA判负环即可。
P.S.这数据范围也太小了吧。。。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>using namespace std;const int MAXN=104,INF=0x3f3f3f3f;int n,m;int head[MAXN],edge=0;struct EDGE {    int v,nxt,w;}e[MAXN];int dis[MAXN],in[MAXN];bool vis[MAXN];inline void adde(int u,int v,int w) {    e[++edge].nxt=head[u],e[edge].v=v,e[edge].w=w,head[u]=edge;}inline bool spfa() {    ++n;    queue<int> q;    for (int i=0;i<n;++i) vis[i]=true,in[i]=1,dis[i]=0,q.push(i);    while (!q.empty()) {        int p=q.front();        q.pop();        vis[p]=false;        for (int i=head[p];~i;i=e[i].nxt) {            int v=e[i].v;            if (dis[v]>dis[p]+e[i].w) {                dis[v]=dis[p]+e[i].w;                if (!vis[v]) {                    vis[v]=true;                    q.push(v);                    if (++in[v]>n) return false;                }            }        }    }    return true;}int main() {//  freopen("hdu 1531.in","r",stdin);    while (scanf("%d%d",&n,&m)&&n) {        edge=0;        memset(head,-1,sizeof(head));        for (int i=0;i<m;++i) {            int u,len,k;            char ss[5];            scanf("%d%d%s%d",&u,&len,ss,&k);            if (ss[0]^'l') adde(u+len,u-1,-k-1);            else adde(u-1,u+len,k-1);        }        puts(spfa()?"lamentable kingdom":"successful conspiracy");    }    return 0;}
原创粉丝点击