懒得复制题面,戳我戳我


Question:

(因为网上找不到好的翻译,这里简单复述一下)

告诉你\(m1+m2\)个约束条件,然后要你找出\(X_1-X_n\)这些数字,求满足要求的数列中不同的数字个数最多有多少个(exp:\(1,2,3,3,2\)里面就有三个不同的数)

Solution:

  • 首先的差分约束的连边很简单
for(int i=1;i<=m1;i++){
int x,y;scanf("%d%d",&x,&y);
add(x,y,1);add(y,x,-1);be[x]=be[y]=true;
}
for(int i=1;i<=m2;i++){
int x,y;scanf("%d%d",&x,&y);
add(x,y,0);be[x]=be[y]=true;
}
  • 然后我们要知道的就是在不同的强联通分量里面的数是不会相互影响的,因为如果不再一个强联通分量中一定是连的\(0\)边,所以我们就只用把\(0\)边连向的那个强联通分量全部变大一些就可以了
  • 所以我们就可以缩点(只用求出每个点在哪个强联通分量中就可以了),如果存在某个强连通中存在正环,就一定是不能找到一组满足的数值,输出\(NIE\)就好。
  • 然后我们就在每个不同的强联通分量中求最长路,这个强联通中的最多不同数值就是最长路数值\(+1\),然后把每个强联通的贡献相加就好了
  • PS:在求每个强联通时最好每个点作为初始点进行\(SPFA\),求出这个点为初始点时的最长路,所以嘞我们应该是可以用\(Floyd\)来做的。

我觉得我的代码打的很繁琐,所以看不看也无所谓了,另外我这个代码可以优化的就是可以在最后面求值是判断正环存在,应该可以适当减低时间复杂度


Code:

//It is coded by Ning_Mew on 4.2
#include<bits/stdc++.h>
using namespace std; const int maxn=607;
const int maxm=1e5; int n,m1,m2,INF,ans=0;
bool be[maxn];
int dist[maxn],vis[maxn],TT[maxn],vs[maxn];
int head[maxn],cnt=0,dfn[maxn],low[maxn],ct=0;
int color[maxn],num_color=0,team[maxn],last=1;
bool instack[maxn];
struct Edge{
int nxt,to,dis;
}edge[maxm*2];
bool choose[maxn]; void add(int from,int to,int dis){
edge[++cnt].nxt=head[from];
edge[cnt].to=to;
edge[cnt].dis=dis;
head[from]=cnt;
} bool SPFA(int k,int ls,int num){
queue<int>Q;while(!Q.empty())Q.pop();
Q.push(k);vis[k]=ls;be[k]=false;dist[k]=0;
TT[k]=1;vs[k]=ls;
while(!Q.empty()){
int u=Q.front();Q.pop();vis[u]=ls-1;
for(int i=head[u];i!=0;i=edge[i].nxt){
int v=edge[i].to;be[v]=false; if(num==-1||color[v]==num);else continue; if(dist[v]<dist[u]+edge[i].dis){
dist[v]=dist[u]+edge[i].dis;
if(dist[v]>n)return false;
if(vis[v]!=ls){
vis[v]=ls;Q.push(v);
if(vs[v]!=ls){
vs[v]=ls; TT[v]=1;
}else{ TT[v]++; }
}
}
}
}return true;
}
void tarjan(int u){
dfn[u]=++ct;low[u]=ct;team[last]=u;last++;instack[u]=true;
for(int i=head[u];i!=0;i=edge[i].nxt){
int v=edge[i].to;
if(dfn[v]==0){tarjan(v); low[u]=min(low[u],low[v]);
}else{if(instack[v])low[u]=min(low[u],dfn[v]);}
}
int v=-100;
if(dfn[u]==low[u]){
num_color++;
do{v=team[--last];color[v]=num_color;instack[v]=false;
}while(v!=u);
}return;
}
int lls=1;
int find(int c){
int re=-0x5f,maxx=-0x5f,minn=0x5f;
for(int i=1;i<=n;i++){
if(color[i]!=c)continue;
//memset(vis,0,sizeof(vis));
memset(dist,-0x5f,sizeof(dist));
SPFA(i,++lls,color[i]);
maxx=-0x5f;minn=0x5f; //cout<<"-----"<<' '<<c<<endl;
//for(int j=1;j<=n;j++)
// cout<<j<<' '<<color[j]<<' '<<dist[j]<<endl; for(int j=1;j<=n;j++){
if(color[j]!=c)continue;
if(dist[j]==INF)continue;
maxx=max(maxx,dist[j]);
minn=min(minn,dist[j]);
}
re=max(re,maxx-minn);
//cout<<re<<endl;
}
//cout<<"ANS:"<<c<<' '<<re<<endl;
return re;
}
int main(){
scanf("%d%d%d",&n,&m1,&m2);
memset(be,false,sizeof(be));
for(int i=1;i<=m1;i++){
int x,y;scanf("%d%d",&x,&y);
add(x,y,1);add(y,x,-1);be[x]=be[y]=true;
}
for(int i=1;i<=m2;i++){
int x,y;scanf("%d%d",&x,&y);
add(x,y,0);be[x]=be[y]=true;
}
int ls=1;
memset(dist,-0x5f,sizeof(dist));
INF=dist[0];
for(int i=1;i<=n;i++){
if(be[i]){
if(SPFA(i,++ls,-1));else{printf("NIE\n");return 0;}
}
}
for(int i=1;i<=n;i++)if(dist[i]==INF)dist[i]=0;
//for(int i=1;i<=n;i++)cout<<"num:"<<i<<' '<<dist[i]<<endl;
//cout<<"SPFA finished"<<endl;
memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));
for(int i=1;i<=n;i++){
if(dfn[i]==0)tarjan(i);
}
//for(int i=1;i<=n;i++)cout<<"num:"<<i<<' '<<color[i]<<endl;
memset(choose,false,sizeof(choose));
for(int i=1;i<=n;i++){
if(choose[ color[i] ]==true)continue;
choose[ color[i] ]=true;
int box=find(color[i]);ans+=(box+1);
//cout<<i<<' '<<color[i]<<' '<<box<<endl;
}
printf("%d\n",ans);
return 0;
}

【题解】 [POI2012]FES-Festival (差分约束)的更多相关文章

  1. [Poi2012]Festival 差分约束+tarjan

    差分约束建图,发现要在每个联通块里求最长路,600,直接O(n3) floyed #include<cstdio> #include<cstring> #include< ...

  2. bzoj 2788 [Poi2012]Festival 差分约束+tarjan+floyd

    题目大意 有n个正整数X1,X2,...,Xn,再给出m1+m2个限制条件,限制分为两类: 1.给出a,b (1<=a,b<=n),要求满足Xa + 1 = Xb 2.给出c,d (1&l ...

  3. BZOJ 3436: 小K的农场 差分约束

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=3436 题解: 裸的差分约束: 1.a>=b+c  ->  b<=a-c ...

  4. BZOJ-2330-[SCOI2011]糖果(差分约束)

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

  5. 【最短路·差分约束】洛谷P1250

    题目描述 一条街的一边有几座房子.因为环保原因居民想要在路边种些树.路边的地区被分割成块,并被编号成1..N.每个部分为一个单位尺寸大小并最多可种一棵树.每个居民想在门前种些树并指定了三个号码B,E, ...

  6. 【BZOJ3436】小K的农场 差分约束

    [BZOJ3436]小K的农场 Description 背景 小K是个特么喜欢玩MC的孩纸... 描述 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了, ...

  7. POJ3169:Layout(差分约束)

    Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15705   Accepted: 7551 题目链接:http ...

  8. hdoj--1384--Intervals(差分约束)

    Intervals Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  9. POJ1201Intervals(差分约束)

    题意 给出数轴上的n个区间[ai,bi],每个区间都是连续的int区间. 现在要在数轴上任意取一堆元素,构成一个元素集合V 要求每个区间[ai,bi]和元素集合V的交集至少有ci不同的元素 求集合V最 ...

随机推荐

  1. Ubuntu下搭建Ruby On Rails

    Ruby on Rails是一个非常高效的Web应用程序框架由David Heinemeier Hansson使用Ruby语言编写. 这是一个开源 Ruby 框架,用于开发数据库支持的Web应用程序. ...

  2. 2018-3-7 20155317 王新玮 Exp1 PC平台逆向破解(5)M

    2018-3-7  20155317  王新玮 Exp1 PC平台逆向破解(5)M 任务要求:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数. NOP.JNE.JE.JMP.CM ...

  3. Android开发——断点续传原理以及实现

    0.  前言 在Android开发中,断点续传听起来挺容易,在下载一个文件时点击暂停任务暂停,点击开始会继续下载文件.但是真正实现起来知识点还是蛮多的,因此今天有时间实现了一下,并进行记录.本文原创, ...

  4. Spring集成Swagger,Java自动生成Api文档

    博主很懒... Swagger官网:http://swagger.io GitHub地址:https://github.com/swagger-api 官方注解文档:http://docs.swagg ...

  5. Js读取XML文件为List结构

    习惯了C#的List集合,对于Javascript没有list 极为不舒服,在一个利用Js读取XML文件的Demo中,决定自己构建List对象,将数据存入List. 第一步,Js读取XML文件知识 X ...

  6. Hadoop开发第3期---Hadoop的伪分布式安装

    一.准备工作 1. 远程连接工具的安装 PieTTY 是在PuTTY 基础上开发的,改进了Putty 的用户界面,提供了多语种支持.Putty 作为远程连接linux 的工具,支持SSH 和telne ...

  7. 【干货】YUM安装PHP 7版本后,增加phalcon框架的报错解决

    目录 1.yum安装php 7.x版本,此处部署7.3版本 2.安装phalcon框架 2.1.PHP版本依赖关系 2.2.编译phalcon扩展模块 2.3.增加扩展文件 3.部署phalcon遇到 ...

  8. 5.Xilinx RapidIO核例子工程源码分析

    https://www.cnblogs.com/liujinggang/p/10091216.html 一.软件平台与硬件平台 软件平台: 操作系统:Windows 8.1 64-bit 开发套件:V ...

  9. libgdx相关知识点

    Gdx.graphics.setContinuousRendering(false); 设置图像为非连续自动渲染. 设置Opengl的混合模式,支持alpha属性 Gdx.gl.glBlendFunc ...

  10. Egret(白鹭引擎)——Egret+fairyGui 实战项目入门

    前言 一行白鹭上青天 需求 最近,我们老板刷刷的为了省事,给美术减压(背景有点长,不说了). 美术出 fairygui,我需要在网页上看到实时操作,并且看到效果! 需求分析 这怕是要了我的狗命啊,但是 ...