【SCOI2011】【差分约束系统】糖果

来源:互联网 发布:excel数据图表插件 编辑:程序博客网 时间:2024/04/29 09:02

这道题应该是一道比较裸的差分约束系统

按照题意建图:

1果A和B一样-> 连边(A,B,0),(B,A,0)

2、如果A小于B ->连边(A,B,1)

3、如果A大于等于B ->连边(B,A,0)

4如果A大于B-> 连边(B,A,1)

5如果A小于等于B -> (A,B,0)

其中第2种情况和第4种情况要特判,若a == b则无解。

这样建好后用spfa求一次最长路就可以了。

代码:

#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>using namespace std;const int maxn = 100000 + 10;const int maxm = maxn * 2;struct pnode{int d,w;pnode *next;pnode(){}pnode(int d,int w,pnode *next):d(d),w(w),next(next){}}*first[maxn],__[maxm],*tot = __;long long dis[maxn];int que[maxm],cnt[maxn];bool done[maxn];int l,r;int n,k;void init(){freopen("bzoj2330.in","r",stdin);freopen("bzoj2330.out","w",stdout);}bool spfa(){while(l < r){int u = que[l++];l %= maxm;done[u] = false;for(pnode *p = first[u];p != NULL;p = p -> next){int v = p -> d;if(dis[u] + p -> w > dis[v]){dis[v] = dis[u] + p -> w;if(++cnt[v] >= n)return false;if(!done[v]){done[v] = true;que[r++] = v;r %= maxm;}}}}return true;}void solve(){memset(done,false,sizeof(done));l = r = 0;for(int i = 1;i <= n;i++){dis[i] = 1;done[i] = true;que[r++] = i;}if(!spfa()){printf("-1\n");return;}long long ans = 0;for(int i = 1;i <= n;i++)ans += dis[i];printf("%lld\n",ans);}void readdata(){scanf("%d%d",&n,&k);for(int i = 1;i <= k;i++){int x,u,v;scanf("%d%d%d",&x,&u,&v);if(x == 1){first[u] = new(tot++)pnode(v,0,first[u]);first[v] = new(tot++)pnode(u,0,first[v]);}if(x == 2){if(u == v)printf("-1\n"),exit(0);first[u] = new(tot++)pnode(v,1,first[u]);}if(x == 3)first[v] = new(tot++)pnode(u,0,first[v]);if(x == 4){first[v] = new(tot++)pnode(u,1,first[v]);if(u == v)printf("-1\n"),exit(0);}if(x == 5)first[u] = new(tot++)pnode(v,0,first[u]);}}int main(){init();readdata();solve();return 0;}



原创粉丝点击