题目大意:维护 M 个差分约束关系,问是否可以满足所有约束,如果满足输出一组解。\(N<=1e5\)

题解:差分约束模型可以通过构建一张有向图来求解。是否满足所有约束可以利用 spfa 进行判断,但是这道题数据范围是 1e5,spfa 很可能会被卡。重新考虑无解的情况,若满足最短路约束,则图中存在负环无解,最长路约束的情况则是存在正环无解。可以利用这一性质,对整个有向图进行 scc 缩点,若一个强连通分量中的边权和大于 0,则无解。缩点之后,在 DAG 上执行 dp 即可求得一组符合条件的解。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
typedef long long ll; inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
} struct node{
int nxt,to,w;
}e[maxn<<1];
int tot=1,head[maxn];
inline void add_edge(int from,int to,int w){
e[++tot]=node{head[from],to,w},head[from]=tot;
} int n,m;
int dfs_clk,dfn[maxn],low[maxn],stk[maxn],top,in[maxn];
vector<pair<int,int>> G[maxn];
int scc,cor[maxn],size[maxn],indeg[maxn],dp[maxn];
queue<int> q; void read_and_parse(){
n=read(),m=read();
for(int i=1,opt,x,y;i<=m;i++){
opt=read(),x=read(),y=read();
if(opt==1)add_edge(x,y,0),add_edge(y,x,0);
else if(opt==2)add_edge(x,y,1);
else if(opt==3)add_edge(y,x,0);
else if(opt==4)add_edge(y,x,1);
else if(opt==5)add_edge(x,y,0);
}
for(int i=1;i<=n;i++)add_edge(0,i,1);
} void tarjan(int u){
dfn[u]=low[u]=++dfs_clk;
stk[++top]=u,in[u]=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]);
else if(in[v])low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
++scc;int v;
do{
v=stk[top--],in[v]=0;
cor[v]=scc,++size[scc];
}while(v!=u);
}
} void topo(){
for(int i=1;i<=scc;i++)if(!indeg[i])q.push(i);
while(q.size()){
int u=q.front();q.pop();
for(int i=0;i<G[u].size();i++){
int v=G[u][i].first,w=G[u][i].second;
dp[v]=max(dp[v],dp[u]+w);
if(!--indeg[v])q.push(v);
}
}
} void solve(){
tarjan(0);
for(int u=0;u<=n;u++)
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to,w=e[i].w;
if(cor[v]==cor[u]){
if(w)return (void)puts("-1");
continue;
}
else G[cor[u]].push_back(make_pair(cor[v],w)),++indeg[cor[v]];
}
topo();
ll ans=0;
for(int i=1;i<=scc;i++)ans=ans+(ll)size[i]*dp[i];
printf("%lld\n",ans);
} int main(){
read_and_parse();
solve();
return 0;
}

【洛谷P3275】糖果的更多相关文章

  1. 洛谷P3275 [SCOI2011]糖果(差分约束,最长路,Tarjan,拓扑排序)

    洛谷题目传送门 差分约束模板题,等于双向连0边,小于等于单向连0边,小于单向连1边,我太蒻了,总喜欢正边权跑最长路...... 看遍了讨论版,我是真的不敢再入复杂度有点超级伪的SPFA的坑了 为了保证 ...

  2. 洛谷P3275 [SCOI2011]糖果 [差分约束系统]

    题目传送门 糖果 题目描述 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比 ...

  3. 洛谷——P3275 [SCOI2011]糖果

    P3275 [SCOI2011]糖果 差分约束模板题,基本思路就是$d[v]+w[v,u]<=d[u]$,$Spfa$更新方法, 有点套路的是要建立原点,即图中不存在的点来向每个点加边,但同样这 ...

  4. 【POJ 3159】Candies&&洛谷P3275 [SCOI2011]糖果

    来补一下自己很久以前那个很蒟蒻很蒟蒻的自己没有学懂的知识 差分约束,说白了就是利用我们在求最短路的一个\(relax\)操作时的判断的原理 \[dis[v]>dis[u]+disj(u,v)\] ...

  5. 题解——洛谷P3275 [SCOI2011]糖果

    一道条件非常多的差分约束 把\( a < b \)转化为\( a-b \le -1\)就可做了 \( a>b \)的情况同理 若有负环则无解输出-1 注意本题中要求每个人都有糖果 所以假设 ...

  6. 洛谷 P3275 BZOJ 2330 [SCOI2011]糖果

    题目描述 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配 ...

  7. 洛谷P3275 [SCOI2011]糖果 题解

    题目链接: https://www.luogu.org/problemnew/show/P3275 分析: 本题就是一个裸的差分约束. 核心: x=1x=1x=1时,a=b,a−>b,b−> ...

  8. 洛谷P3275 [SCOI2011]糖果(差分约束)

    题目描述 幼儿园里有 $N$ 个小朋友,$lxhgww $老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的 ...

  9. 洛谷P3275 [SCOI2011]糖果

    差分约束大坑题 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring ...

随机推荐

  1. servlet ServletContext

    一.Servlet简介 1.什么是Servlet Servlet 运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求.响应给浏览器的动态资源.但servlet的实质就是 ...

  2. day 7-12 数据库的基本操作和存储引擎

    一. 储备知识 数据库服务器:一台高性能计算机 数据库管理系统:mysql(mssql等),是一个软件 数据库:db1(student_db),是一个文件夹 表:studen_info 是一个文件 记 ...

  3. day 7-3 僵尸进程,孤儿进程与守护进程

    一.基本定义 正常情况下,子进程是通过父进程创建的,子进程在创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 当一个 进程完成它的工作终止之后,它 ...

  4. Java集合和数组的区别

    参考:Java集合和数组的区别 集合和容器都是Java中的容器. 区别 数组特点:大小固定,只能存储相同数据类型的数据 集合特点:大小可动态扩展,可以存储各种类型的数据   转换 数组转换为集合: A ...

  5. vue表單

    使用v-model進行表單雙向數據綁定. 可以根據控件決定數據的類型,可以綁定input.單選.複選.下拉框等 可以使用number和trim等修飾符.

  6. mysql必须知道的

    https://blog.csdn.net/xlgen157387/article/details/73691848

  7. Jarvis OJ A Piece Of Cake

    看图片的隐写术自闭,本来想看一看jarvisoj 的basic放松一下心情,结果一道题就做了一晚上qwq 首先看到这道题的时候想到的是凯撒密码(这其实是Google之后才知道这个名字的)枚举了26种位 ...

  8. ie11的版本判断

    我的电脑昨天更新的时候把ie11给更新出来了,然后发现我的skylineweb项目提示我的浏览器不是ie,这样显然是浏览器检测出现了问题.查找后找到了下面的解决方法.大家的电脑如果也更新成了ie11的 ...

  9. 最简单的socket服务器与客户端

    服务器: //服务器 #include <stdio.h> #include <netinet/in.h> #include <unistd.h> #include ...

  10. 使用aapt查看当前apk的属性

    android:versioncode——整数值,代表应用程序代码的相对版本,也就是版本更新过多少次. android:versionname——字符串值,代表应用程序的版本信息,需要显示给用户. e ...