BZOJ2788/POI2012 Festival
来源:互联网 发布:泰达网络登录 编辑:程序博客网 时间:2024/06/05 06:57
Task
有n个正整数X1,X2,…,Xn,再给出m1+m2个限制条件,限制分为两类:
1. 给出a,b (1<=a,b<=n),要求满足Xa + 1 = Xb
2. 给出c,d (1<=c,d<=n),要求满足Xc <= Xd
在满足所有限制的条件下,求集合{Xi}大小的最大值。
2<=n<=600, 1<=m1+m2<=100,000.
Solution
1.差分约束:
把Xa+1=Xb转化为Xa+1<=Xb,Xa+1>=Xb,建一条a到b边权为1的边,b到a权值为-1的边.
把Xc<=Xd转化为 Xc-Xd<=0,建一条d到c边权为0的有向边.
建图之后就可以把问题转化为求图中任意两点最短路的最大值.
2.强连通缩点:
图中显然有环,通过强连通转化为DAG,考虑每个强联通分量之间的关系:
假如有一条从a到b的边,说明Xa>=Xb,但两者之间没有具体大小关系,那么我们就能保证存在一组解使得a,b的点权值不重复,那么最终的答案就是每个强连通分量的答案之和.
3.求最短路的最大值:
图中显然可能出现负环,那么就不能用dijkstra算法求最短路.我们可以通过Floyd或者SPFA判断是否有负环,若存在负环,即无解,否则求最短路.
Code
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>using namespace std;const int M=200005;const int N=605;int head[N],scc=0,ec=0,n,m1,m2,dfn[N],low[N],Clock=0,stk[N],top=0,id[N],p[N],sum[N][N];int dis[N][N],inq[N],cnt[N],Q[M*10];struct node{ int to,v,nex;}e[M<<1];inline void rd(int &res){ res=0;char c; while(c=getchar(),c<48); do res=(res<<1)+(res<<3)+(c^48); while(c=getchar(),c>=48);}void ins(int a,int b,int c){ e[ec]=(node){b,c,head[a]}; head[a]=ec++;}void Tarjan(int x){ dfn[x]=low[x]=++Clock; stk[++top]=x; inq[x]=1; for(int i=head[x];~i;i=e[i].nex){ int y=e[i].to; if(!dfn[y]){ Tarjan(y); low[x]=min(low[x],low[y]); } else if(inq[y])low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]){ scc++; while(1){ sum[scc][0]++; sum[scc][sum[scc][0]]=stk[top]; inq[stk[top]]=0; id[stk[top--]]=scc; if(stk[top+1]==x)break; } }}int Find_(int k){ int l=0,r=0,i,j,mipath=0; Q[r++]=p[k]; int s=p[k]; dis[s][s]=0; while(l<r){ int x=Q[l++]; cnt[x]++; inq[x]=0; if(cnt[x]>sum[k][0])return -1; for(i=head[x];~i;i=e[i].nex){ int y=e[i].to; if(id[y]!=k)continue; if(dis[s][y]>dis[s][x]+e[i].v){ dis[s][y]=dis[s][x]+e[i].v; if(!inq[y]){ Q[r++]=y; inq[y]=1; } } } } for(i=1;i<=sum[k][0];i++){ mipath=max(mipath,dis[s][sum[k][i]]); } return mipath;}int solve(){ int i,ans=0; for(i=1;i<=n;i++){ if(!dfn[i])Tarjan(i); } for(i=1;i<=scc;i++){ int b=0; for(int j=1;j<=sum[i][0];j++){ p[i]=sum[i][j]; for(int k=1;k<=sum[i][0];k++){ int y=sum[i][k]; cnt[y]=0,inq[y]=0,dis[p[i]][y]=2e9; } int a=Find_(i); if(a==-1)return -1; b=max(b,a); } ans+=b+1; } return ans;}int main(){ memset(head,-1,sizeof(head)); int i,j,a,b,c,k; rd(n);rd(m1);rd(m2); for(i=1;i<=m1;i++){ rd(a);rd(b);//a+1=b,-> a+1<=b,a+1>=b -> a-b<=-1,b-a<=1 a->b 1 ins(a,b,1); ins(b,a,-1); } for(i=1;i<=m2;i++){ rd(a);rd(b);//b>=a a-b<=0 ins(b,a,0); } int res=solve(); if(~res)printf("%d\n",res); else puts("NIE"); return 0; }
0 0
- BZOJ2788: [Poi2012]Festival
- BZOJ2788/POI2012 Festival
- BZOJ2788: [Poi2012]Festival 差分约束
- [BZOJ2788][Poi2012]Festival(差分约束+floyed+tarjan)
- [bzoj2788][Poi2012]Festival floyd 差分约束系统 tarjan
- bzoj2788 [Poi2012]Festival(差分约束+floyd+tarjan缩点)
- [BZOJ2788]-[Poi2012]Festival-差分约束+tarjan+floyd
- [Poi2012]Festival
- BZOJ 2788: [Poi2012]Festival
- [Poi2012] bzoj 2788 Festival
- 差分约束+tarjin [Poi2012]Festival
- [Poi2012]Festival 差分约束+tarjan
- BZOJ 2788 [Poi2012]Festival 差分约束+tarjan+floyd
- BZOJ 2788 Poi2012 Festival 差分约束+Tarjan+Floyd
- bzoj 2788 [Poi2012]Festival tarjan+floyd+差分约束
- bzoj 2788: [Poi2012]Festival (差分约束+最短路+tarjan)
- POI2012题解
- Spring Festival
- xml 中画圆角矩形、虚线、实线
- MFC中ListControl控件的使用
- IntelliJ IDEA 12创建Maven管理的Java Web项目(图解)
- 数据库设计原则
- 浅谈单例模式的几种写法
- BZOJ2788/POI2012 Festival
- python实现12306查询火车票
- iOS友盟第三方登陆开发
- 中国省市县(区)json数据下载
- JS组件系列——Bootstrap 树行控件使用经验分享
- shell获取进程ID
- STM32 定时器用于外部脉冲计数
- Three Ways to Inject Your Code into Another Process
- S5PV210之探索时钟