【题解】 [POI2012]FES-Festival (差分约束)
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 (差分约束)的更多相关文章
- [Poi2012]Festival 差分约束+tarjan
差分约束建图,发现要在每个联通块里求最长路,600,直接O(n3) floyed #include<cstdio> #include<cstring> #include< ...
- 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 ...
- BZOJ 3436: 小K的农场 差分约束
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=3436 题解: 裸的差分约束: 1.a>=b+c -> b<=a-c ...
- BZOJ-2330-[SCOI2011]糖果(差分约束)
Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的 ...
- 【最短路·差分约束】洛谷P1250
题目描述 一条街的一边有几座房子.因为环保原因居民想要在路边种些树.路边的地区被分割成块,并被编号成1..N.每个部分为一个单位尺寸大小并最多可种一棵树.每个居民想在门前种些树并指定了三个号码B,E, ...
- 【BZOJ3436】小K的农场 差分约束
[BZOJ3436]小K的农场 Description 背景 小K是个特么喜欢玩MC的孩纸... 描述 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了, ...
- POJ3169:Layout(差分约束)
Layout Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15705 Accepted: 7551 题目链接:http ...
- hdoj--1384--Intervals(差分约束)
Intervals Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- POJ1201Intervals(差分约束)
题意 给出数轴上的n个区间[ai,bi],每个区间都是连续的int区间. 现在要在数轴上任意取一堆元素,构成一个元素集合V 要求每个区间[ai,bi]和元素集合V的交集至少有ci不同的元素 求集合V最 ...
随机推荐
- [Baltic 2011]Lamp BZOJ2346
分析: 建图最短路,比较裸. 我们可以考虑,如果是‘\’那么,左上连右下边权为0,左下连右上边权为1,反之亦然. 卡裸spfa,加点优化能过,我就直接改成的堆优化Dijkstra 附上代码: #inc ...
- Django:admin后台汉化问题
1.设置admin站点中文显示,即汉化admin后台管理站点. 方法一:修改settings文件 LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' 更改为: LANG ...
- 20155325 Exp5 MSF基础应用
目录 实验内容 遇到的问题 基础问题问答 老师!!!我实验三的C代码已经删除了,请求评分~~~ 实验内容 1.Windows服务渗透攻击--MS08-067 系统 虚拟机 参考博客 Windows X ...
- ZAB协议和Paxos算法
前言在上一篇文章Paxos算法浅析中主要介绍了Paxos一致性算法应用的场景,以及对协议本身的介绍:Google Chubby是一个分布式锁服务,其底层一致性实现就是以Paxos算法为基础的:但这篇文 ...
- A1046. Shortest Distance(20)
17/20,部分超时. #include<bits/stdc++.h> using namespace std; int N,x,pairs; int a,b; vector<int ...
- CryptoZombies学习笔记——Lesson2
第二课是僵尸猎食,将把app变得更像一个游戏,添加多人模式,建立更多创造僵尸的方法. chapter1 依然是简介 chapter2:映射和地址 映射相当于一个索引,指向不同地址,不同地址存储的数据不 ...
- PAT甲题题解-1007. Maximum Subsequence Sum (25)-求最大子区间和
题意:给出n个数,求最大连续的子区间和,并且输出该区间的第一个和最后一个数. 如果所有数都小于0,那么则输出0,第一个数和最后一个数. 看数据k的范围,就知道肯定不能两层for循环来求区间和,O(n^ ...
- 第一次scrum meeting
在这次会议中,我们确定了任务的具体分配.这里截取一部分,每个人都有20个小时左右的编程任务,整个项目共计约140小时. 明天是正式开始软件实现的第一天,下面列出前两天每个人的任务: 第一天 第二天 ...
- 每日scrum(6)
今天是小组正式冲刺的第六天,软件的各种结尾工作,还有一些模块就已经全部实现了: 遇到的问题主要是对于自己能力的担忧,以前总是想,如果自己努力,就会怎样成功,其实并不是那样,小小的距离就是很远的能力差距 ...
- HashMap相关总结
1.HashMap:根据键值hashCode值存储数据,大多数情况下可以直接定位到它的值,但是遍历顺序不确定.所有哈希值相同的值存储到同一个链表中 Ha ...