[BZOJ2788][Poi2012]Festival(差分约束+floyed+tarjan)
来源:互联网 发布:计算机网络就业 知乎 编辑:程序博客网 时间:2024/05/19 12:23
题目描述
传送门
题目大意:有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}大小的最大值。
题解
首先差分约束建图+深搜spfa判断负环->无解
tarjan缩点,不同强连通分量里的点不影响(取值可以没有交集),相同强连通分量里的点的最大取值数为任意两点的最短路的最大值+1
最短路是满足差分约束的条件,可以发现最长的最短路上的点的点权可以按照边权递增,不在这条路上的点的取值一定是它的子集
更科学一点的证明参考popoqqq大爷的题解orz:http://blog.csdn.net/popoqqq/article/details/48249845
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define N 605#define E 300005int n,m1,m2,dfs_clock,top,scc,ans;int tot,point[N],nxt[E],v[E],c[E];int dis[N],d[N][N],dfn[N],low[N],belong[N],stack[N];bool vis[N],flag;void add(int x,int y,int z){ d[x][y]=min(d[x][y],z); ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z;}void spfa(int x){ vis[x]=1; for (int i=point[x];i;i=nxt[i]) if (dis[v[i]]>dis[x]+c[i]) { dis[v[i]]=dis[x]+c[i]; if (vis[v[i]]) { flag=1; return; } spfa(v[i]); if (flag) return; } vis[x]=0;}void floyed(){ for (int k=1;k<=n;++k) for (int i=1;i<=n;++i) if (k!=i) for (int j=1;j<=n;++j) if (k!=j) d[i][j]=min(d[i][j],d[i][k]+d[k][j]);}void tarjan(int x){ dfn[x]=low[x]=++dfs_clock;stack[++top]=x;vis[x]=1; for (int i=point[x];i;i=nxt[i]) if (!dfn[v[i]]) { tarjan(v[i]); low[x]=min(low[x],low[v[i]]); } else if (vis[v[i]]) low[x]=min(low[x],dfn[v[i]]); if (low[x]==dfn[x]) { int now=0;++scc; while (now!=x) { now=stack[top--]; belong[now]=scc; vis[now]=0; } }}int main(){ scanf("%d%d%d",&n,&m1,&m2); memset(d,127/3,sizeof(d)); for (int i=1;i<=n;++i) d[i][i]=0; for (int i=1;i<=m1;++i) { int x,y;scanf("%d%d",&x,&y); add(x,y,1);add(y,x,-1); } for (int i=1;i<=m2;++i) { int x,y;scanf("%d%d",&x,&y); add(y,x,0); } for (int i=1;i<=n;++i) add(0,i,0); memset(dis,127/3,sizeof(dis));dis[0]=0; flag=0;spfa(0); if (flag) {puts("NIE");return 0;} floyed(); memset(vis,0,sizeof(vis)); for (int i=1;i<=n;++i) if (!dfn[i]) tarjan(i); for (int i=1;i<=scc;++i) { int now=0; for (int j=1;j<=n;++j) if (belong[j]==i) for (int k=1;k<=n;++k) if (belong[k]==i) now=max(now,d[j][k]); ans+=now+1; } printf("%d\n",ans);}
0 0
- [BZOJ2788][Poi2012]Festival(差分约束+floyed+tarjan)
- [bzoj2788][Poi2012]Festival floyd 差分约束系统 tarjan
- bzoj2788 [Poi2012]Festival(差分约束+floyd+tarjan缩点)
- [BZOJ2788]-[Poi2012]Festival-差分约束+tarjan+floyd
- BZOJ2788: [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)
- 差分约束+tarjin [Poi2012]Festival
- BZOJ 2788 Festival 详解(差分约束 tarjan floyd)
- BZOJ2788: [Poi2012]Festival
- BZOJ2788/POI2012 Festival
- bzoj 2788(差分约束+tarjan)
- bzoj 2788 / 洛谷3530 差分约束系统+floyd+tarjan
- 【BZOJ2330】【SCOI2011】糖果——差分约束系统+tarjan
- ZOJ1508 (差分约束)
- php版本
- RecyclerView和EditText焦点冲突和输入法软键盘把布局顶出屏幕之外的解决
- HDU-5102-The K-th Distance【思维】【好题】
- Sass mixin
- DES(ecb)加密
- [BZOJ2788][Poi2012]Festival(差分约束+floyed+tarjan)
- Python性能分析
- C语言下程序的堆栈调用(详细,图示)
- POJ-1101_The Game
- 数据结构--平衡二叉树的插入详解
- Codeforces 801D Volatile Kite 几何
- 关于synchronized(object){//} 同步代码块
- 如何用abaqus建造8号槽钢并分析槽钢的受力
- Linux下mariadb的使用