UVA 515 King题解
作者:互联网
来水写一篇差分约束系统的题解。
差分约束相信大家都会,就是写出不等式,然后将题目转化为图上问题即可
这道题目的特殊之处就是用到一个超级源点,超级源点就是这个点与所有的边连一条边权为零的边,便于跑 SPFA (当然跑 bellman 也不拦着你)。
不等式
根据题目找一下不等式
第一种是 \(a_m+\cdots+a_n > W\);
然后转化为前缀和 \(S[n]-S[m-1] \geq W+1\);
第二种是 \(a_m+\cdots+a_n < W\);
转化为前缀和 \(S[n]-S[m-1] \leq W-1\);
然后都转化为大于等于 \(S[n]-S[m-1] \geq 1-W\);
既然是大于等于,再求最长路,判断是否符合就行了。
这道题就是差分约束系统判断是否存在的一类问题,这一类问题有两种情况(当然此题只涉及一种),在此列举一下:
有负环:无解
无约束:无数解
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
const int INF=0x3f3f3f3f;
int head[maxn],cnt;
struct node
{
int nxt,v,w;
}e[maxn<<1];
void add(int u,int v,int w)
{
e[cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt++;
}
int dis[maxn],num[maxn];
bool vis[maxn];
bool spfa(int s)//判负环
{
memset(vis,false,sizeof(vis));
memset(dis,-INF,sizeof(dis));
memset(num,0,sizeof(num));
vis[s]=true;
dis[s]=0; queue<int>q;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];~i;i=e[i].nxt)
{
int v=e[i].v;
if(dis[v]<dis[u]+e[i].w)
{
dis[v]=dis[u]+e[i].w;
if(!vis[v])
{
vis[v]=true;
q.push(v);
if(++num[v]>s+1) return false;
}
}
}
}
return true;
}
int main()
{
int n;
while(scanf("%d",&n)==1,n)
{
int m;
memset(head,-1,sizeof(head));
cnt=0;
scanf("%d",&m);
for(int i=0;i<m;++i)
{
int a,b,w;
char ch[10];
scanf("%d %d %s %d",&a,&b,ch,&w);
if(ch[0]=='g')
{
add(a-1,a+b,w+1);//第一种情况
}
else
{
add(a+b,a-1,1-w);//第二种情况
}
}
for(int i=0;i<=n;++i)
{
add(n+1,i,0);//设置超级源点,可以为0号点,也可以为n+1号点
}
if(spfa(n+1)) puts("lamentable kingdom");
else puts("successful conspiracy");
}
return 0;
}
标签:head,题目,不等式,int,题解,源点,差分,UVA,515 来源: https://www.cnblogs.com/dhrwhy/p/16465201.html