【BZOJ2330】糖果(差分约束系统,强连通分量,拓扑排序)
题意:
幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求。幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。
输入的第一行是两个整数N,K。
接下来K行,表示这些点需要满足的关系,每行3个数字,X,A,B。
如果X=1, 表示第A个小朋友分到的糖果必须和第B个小朋友分到的糖果一样多;
如果X=2, 表示第A个小朋友分到的糖果必须少于第B个小朋友分到的糖果;
如果X=3, 表示第A个小朋友分到的糖果必须不少于第B个小朋友分到的糖果;
如果X=4, 表示第A个小朋友分到的糖果必须多于第B个小朋友分到的糖果;
如果X=5, 表示第A个小朋友分到的糖果必须不多于第B个小朋友分到的糖果;
对于所有的数据,保证 N<=100000,K<=100000,1<=X<=5,1<=A, B<=N
思路:第一反应应该是差分约束系统,但N的范围令人不放心,实际上裸SPFA也需要一些优化才能跑过去
知乎上有几位大佬说这题是tarjan缩点+拓扑排序,确实这种做法理论复杂度才是有保证的
先建立原图,对于等于关系连双向边,小于等于(和大于等于,显然等价)连单向边,先缩一次点,同一个分量里的人糖果数一定相等
再进行拓扑排序计算每一个分量的糖果数,环会导致无解,注意糖果数和前面推导不同时需要取MAX
最后特判下同一个分量里的边有没有不等的,有则无解
SPFA
var q:array[..]of longint;
head,vet,next,len,dis,time:array[..]of longint;
inq:array[..]of boolean;
n,m,i,x,a,b,tot:longint;
ans,tmp:int64; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; procedure spfa;
var t,w,i,u,e,v:longint;
begin
fillchar(time,sizeof(time),);
t:=; w:=-;
for i:= to n do
begin
dis[i]:=; inc(w); q[w]:=i; inq[i]:=true;
end; while t<=w do
begin
u:=q[t mod n]; inc(t); inq[u]:=false;
e:=head[u];
while e<> do
begin
v:=vet[e];
if dis[u]+len[e]>dis[v] then
begin
dis[v]:=dis[u]+len[e];
if not inq[v] then
begin
inc(time[v]);
if time[v]>n then
begin
writeln(-); ans:=-;
exit;
end;
inc(w); q[w mod n]:=v; inq[v]:=true;
end;
end;
e:=next[e];
end;
end;
end; begin read(n,m);
for i:= to m do
begin
read(x,a,b);
if (x and =)and(a=b) then
begin
writeln(-);
exit;
end;
case x of
:begin add(b,a,); add(a,b,); end;
:add(a,b,);
:add(b,a,);
:add(b,a,);
:add(a,b,);
end;
end;
spfa;
if ans= then
begin
for i:= to n do ans:=ans+dis[i]; writeln(ans);
end; end.
tarjan+拓扑排序
#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int M=;
int head[M],vet[M],next[M],len[M],a[M],b[M],c[M],dfn[M],low[M],flag[M],ind[M],stack[M],s[M];
int n,m,i,tot,id,top,cnt;
long long d[M],size[M]; void add(int a,int b,int c)
{
next[++tot]=head[a];
vet[tot]=b;
len[tot]=c;
head[a]=tot;
ind[b]++;
} void swap(int &a,int &b)
{
int t;
t=a;a=b;b=t;
} void dfs(int u)
{
int e,v;
flag[u]=;
stack[++top]=u;
dfn[u]=low[u]=++cnt;
for(e=head[u];e;e=next[e])
{
v=vet[e];
if(!flag[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(!s[v]) low[u]=min(low[u],low[v]);
}
if(low[u]==dfn[u])
{
id++;
while(stack[top]!=u)
{
s[stack[top]]=id;
size[id]++;
top--;
}
s[stack[top]]=id;
size[id]++;
top--;
} } long long solve()
{
queue<int> q;
int num;
long long sum;
for(int i=;i<=id;i++)
if(!ind[i])
{
q.push(i);
d[i]=;
}
if(q.empty()) return -;
num=;
while(!q.empty())
{
int u=q.front(); q.pop(); num++;
for(int e=head[u];e;e=next[e])
{
int v=vet[e];
ind[v]--;
d[v]=max(d[v],d[u]+len[e]);
if(!ind[v]) q.push(v);
}
}
if(num<id) return -;
else
{
sum=;
for(int i=;i<=id;i++) sum=sum+d[i]*size[i];
return sum;
} } int main()
{
// freopen("bzoj2330.in","r",stdin);
// freopen("bzoj2330.out","w",stdout);
scanf("%d%d",&n,&m);
id=;
for(i=;i<=m;i++)
{
scanf("%d%d%d",&a[i],&b[i],&c[i]);
if(a[i]==||a[i]==) swap(b[i],c[i]);
if(a[i]==)
{
add(b[i],c[i],);
add(c[i],b[i],);
}
if(a[i]==||a[i]==) add(b[i],c[i],);
}
for(i=;i<=n;i++)
if(!flag[i]) dfs(i);
//printf("%d\n",id);
memset(head,,sizeof(head));
memset(ind,,sizeof(ind));
tot=;
for(i=;i<=m;i++)
if(s[b[i]]!=s[c[i]])
{
if(a[i]==||a[i]==) add(s[b[i]],s[c[i]],);
else add(s[b[i]],s[c[i]],);
}
else
{
if(a[i]==||a[i]==)
{
printf("-1\n");
return ;
}
}
printf("%lld\n",solve());
return ;
}
【BZOJ2330】糖果(差分约束系统,强连通分量,拓扑排序)的更多相关文章
- BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP
BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP Description In an effort to better manage t ...
- BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset
BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i ...
- poj 2762(强连通分量+拓扑排序)
题目链接:http://poj.org/problem?id=2762 题意:给出一个有向图,判断任意的两个顶点(u,v)能否从u到达v,或v到达u,即单连通,输出Yes或No. 分析:对于同一个强连 ...
- BZOJ1924:[SDOI2010]所驼门王的宝藏(强连通分量,拓扑排序)
Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...
- 2019ICPC(银川) - Delivery Route(强连通分量 + 拓扑排序 + dijkstra)
Delivery Route 题目:有n个派送点,x条双向边,y条单向边,出发点是s,双向边的权值均为正,单向边的权值可以为负数,对于单向边给出了一个限制:如果u->v成立,则v->u一定 ...
- CDOJ 图论专题 A.不是图论 强连通分量+拓扑排序 经典
题目链接 在其中纠错第一次wa代码 #include <cstdio> #include <cstring> #include <cstdlib> #includ ...
- POJ 2762 Going from u to v or from v to u?(强连通分量+拓扑排序)
职务地址:id=2762">POJ 2762 先缩小点.进而推断网络拓扑结构是否每个号码1(排序我是想不出来这点的. .. ).由于假如有一层为2的话,那么从此之后这两个岔路的点就不可 ...
- bzoj2330: [SCOI2011]糖果 差分约束系统
幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候 ...
- 【bzoj2330】[SCOI2011]糖果 差分约束系统
题目描述 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配 ...
- [BZOJ2330][SCOI2011]糖果 差分约束系统+最短路
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2330 类似于题目中这种含有不等式关系,我们可以建立差分约束系统来跑最长路或最短路. 对于一 ...
随机推荐
- E. Dasha and Puzzle 数学题
http://codeforces.com/contest/761/problem/E 给出一颗树,要求在坐标系中用平行于坐标轴的线描绘出来. 要求边不能相交,而且点的坐标唯一. 注意到2^1 + 2 ...
- 把sed当作命令解释器使用
[root@sishen ~]# vim script.sed #!/bin/sed -f #交换第一列和第二列 s/\([^,]*\),\([^,]*\),\(.*\).*/\2,\1, \3/g ...
- 用js的eval函数模拟Web API中的onclick事件
在检查组内小伙伴提交的tabToggler插件的js代码时,发现了onclick的如下用法: el.onclick = function(){ //按钮样式切换 for(var i=0;i<ob ...
- webpack3整理(第二节/满三节)
消除未使用的CSS:安装PurifyCSS-webpack插件 cnpm i purifycss-webpack purify-css -D const glob = require('glob'); ...
- webpack2版本四个核心概念
webpack 是一个现代的 JavaScript 应用程序的模块打包器(module bundler) 四个核心概念: --------------------------------------- ...
- vue HTTP请求(针对vue-resource)
//初始化页面需要做什么事情 //点击后需要做什么事情 //鼠标.键盘.冒泡.默认行为等事件 //前端调用接口就是按需展示数据//created和mounted里面都可以做数据处理,唯一不同的是cre ...
- <在此处打开命令窗口>替换为PowerShell打开模式
Windows7中Shift+右键"在此处打开命令窗口"默认是采用cmd的方式打开. 把cmd替换为PowerShell的方式打开. 1. Ctrl + R 输入regedit进入 ...
- Python界面编程之六----布局
布局(转载于–学点编程吧)通过实践可知采用了布局之后能够让我们的程序在使用上更加美观,不会随着窗体的大小发生改变而改变,符合我们的使用习惯. 绝对位置程序员以像素为单位指定每个小部件的位置和大小. 当 ...
- Django 跨域CORS
现在,前端与后端分处不同的域名,我们需要为后端添加跨域访问的支持. 我们使用CORS来解决后端对跨域访问的支持. 使用django-cors-headers扩展 参考文档https://github. ...
- day24-1 元类
目录 元类 类的组成 内置函数 exec() class关键字创建类原理 自定义元类控制类的创建 自定义元类控制类实例化 自定义元类后对象属性查找顺序 元类 在python中一切皆对象,name我们用 ...