[二分答案 2-SAT验证 前后缀优化建图] Codeforces 587D #326 (Div. 1) D. Duff in Mafia
来源:互联网 发布:java中main是什么意思 编辑:程序博客网 时间:2024/05/16 07:30
大概题意是删去一组边 这组边是一个匹配
剩下的边 同一颜色的一组边也形成一个匹配
使删去的边最大值最小
这个考虑二分答案 然后检验
- 大于答案的边必然保留
- 同一个点连的同一颜色的边最多保留一条
- 同一个点连的边最多删除一条
这个某些边集最多删一条怎么处理
把他排成一排 那么一个点选了 他的前面都不能选 后面都不能选 那么建前后缀使得边数降到
红点是表示前缀后缀辅助点
#include<cstdio>#include<cstdlib>#include<algorithm>#include<vector>using namespace std;typedef long long ll;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++;}inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=500005;struct edge{ int u,v,next;}G[N*10];int head[N],inum;int _head[N],tmp;inline void add(int u,int v){ int p=++inum; G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;}int pre[N],low[N],clk;int scc[N],cnt; int Stack[N],pnt;#define V G[p].vinline void dfs(int u){ pre[u]=low[u]=++clk; Stack[++pnt]=u; for (int p=head[u];p;p=G[p].next) if (!pre[V]) dfs(V),low[u]=min(low[u],low[V]); else if (!scc[V]) low[u]=min(low[u],pre[V]); if (low[u]==pre[u]){ ++cnt; while (Stack[pnt]!=u) scc[Stack[pnt--]]=cnt; scc[Stack[pnt--]]=cnt; }}int n,m,Tot;int y[N],vc;int size[N],sum[N];inline int pf(int idx,int x){ return (m<<1)+(sum[idx-1]<<1)+x; }inline int sf(int idx,int x){ return (m<<1)+(sum[idx-1]<<1)+size[idx]+x; }inline bool Tarjan(){ for (int i=0;i<Tot;i++) pre[i]=low[i]=scc[i]=0; pnt=cnt=clk=0; for (int i=0;i<Tot;i++) if (!pre[i]) dfs(i); for (int i=0;i<2*m;i+=2) if (scc[i]==scc[i^1]) return 0; return 1;}int us[N],vs[N],ts[N],cs[N];inline bool check(int x){ if (x==3) x=3; for (int i=0;i<m;i++) if (ts[i]>x) add(i<<1,i<<1|1); return Tarjan();}int sx[N],icnt;struct abcd{ int v,c,idx; abcd(int v=0,int c=0,int idx=0):v(v),c(c),idx(idx) { } bool operator < (const abcd &B) const{ return v==B.v?c<B.c:v<B.v; }}edges[N]; int ecnt;int ans[N],kans;int main(){ freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); for (int i=0;i<m;i++) read(us[i]),read(vs[i]),read(cs[i]),read(ts[i]),sx[++icnt]=cs[i]; sort(sx+1,sx+icnt+1); icnt=unique(sx+1,sx+icnt+1)-sx-1; for (int i=0;i<m;i++){ cs[i]=lower_bound(sx+1,sx+icnt+1,cs[i])-sx; edges[++ecnt]=abcd(us[i],cs[i],i); edges[++ecnt]=abcd(vs[i],cs[i],i); } sort(edges+1,edges+ecnt+1); int pnt=1; while (pnt<=ecnt){ ++vc; y[size[vc]++]=edges[pnt++].idx; while (pnt<=ecnt && edges[pnt].v==edges[pnt-1].v && edges[pnt].c==edges[pnt-1].c) y[size[vc]++]=edges[pnt++].idx; for (int j=0;j<size[vc];j++){ if (j-1>=0) add(pf(vc,j),pf(vc,j-1)); add(pf(vc,j),y[j]<<1); if (j+1<size[vc]) add(sf(vc,j),sf(vc,j+1)); add(sf(vc,j),y[j]<<1); } for (int j=0;j<size[vc];j++){ if (j-1>=0) add(y[j]<<1|1,pf(vc,j-1)); if (j+1<size[vc]) add(y[j]<<1|1,sf(vc,j+1)); } sum[vc]=sum[vc-1]+size[vc]; } pnt=1; while (pnt<=ecnt){ ++vc; y[size[vc]++]=edges[pnt++].idx; while (pnt<=ecnt && edges[pnt].v==edges[pnt-1].v) y[size[vc]++]=edges[pnt++].idx; for (int j=0;j<size[vc];j++){ if (j-1>=0) add(pf(vc,j),pf(vc,j-1)); add(pf(vc,j),y[j]<<1|1); if (j+1<size[vc]) add(sf(vc,j),sf(vc,j+1)); add(sf(vc,j),y[j]<<1|1); } for (int j=0;j<size[vc];j++){ if (j-1>=0) add(y[j]<<1,pf(vc,j-1)); if (j+1<size[vc]) add(y[j]<<1,sf(vc,j+1)); } sum[vc]=sum[vc-1]+size[vc]; } Tot=(m<<1)+(sum[vc]<<1); for (int i=0;i<2*m;i++) _head[i]=head[i]; tmp=inum; if (!Tarjan()) { printf("No\n"); return 0; } int L=-1,R=1<<30,MID; while (L+1<R){ if (check(MID=(L+R)>>1)) R=MID; else L=MID; for (int i=0;i<2*m;i++) head[i]=_head[i]; inum=tmp; } check(R); printf("Yes\n"); for (int i=0;i<m;i++){ ans[i]=scc[i<<1|1]<scc[i<<1]; if (!ans[i]) kans++; } printf("%d %d\n",R,kans); for (int i=0;i<m;i++) if (!ans[i]) printf("%d ",i+1); return 0;}
0 0
- [二分答案 2-SAT验证 前后缀优化建图] Codeforces 587D #326 (Div. 1) D. Duff in Mafia
- [二分 前缀优化建图 2-SAT] Codeforces 587D. Duff in Mafia
- [ 前后缀优化建图 2-SAT ] Codeforces587D Duff in Mafia
- Codeforces Round #326 (Div. 2) D. Duff in Beach
- [二分答案 2-SAT验证 前缀后缀优化建图 线段树优化建图] Codeforces gym 100159 Facebook Hacker Cup 2012 I. Unfriending
- Codeforces Round #326 (Div. 2) D. Duff in Beach(LIS)
- codeforces #326 D. Duff in Beach (dp)
- Codeforces Round #400 (Div. 1 + Div. 2, combined) D. The Door Problem(二分染色?/2-sat,好题)
- codeforces#326-D - Duff in Beach- dp+分块
- Codeforces 854D Jury Meeting【思维+前后缀和+二分】
- Codeforces Round #400 (Div. 1 + Div. 2, combined)D. The Door Problem【2-sat Tarjan+思维建图】
- 【Codeforces Round 326 (Div 2)D】【DP】Duff in Beach 数列重复取数最多k次使得单调不下降
- Codeforces Round #320 (Div. 2) D. "Or" Game(贪心 前后缀)
- Codeforces Round #433 (Div. 2) D. Jury Meeting(思维 贪心 前后缀)
- Codeforces Round #251 (Div. 2) D 二分
- Codeforces Round #352 (Div. 2) D 二分
- Codeforces Round #377 (Div. 2) D 二分
- Codeforces Round #350 (Div. 2) D2. Magic Powder - 2 670D 【二分答案】
- linux系统修改系统时间重启后导致文件系统错误原因以及修复方法
- iOS 10 开发适配系列 之 权限Crash问题
- Android获取可用内存(系统,sd卡,u盘)
- ubuntu下安装php5.6开发环境sudo apt-get install phpmyadmin sudo apt-get install php-mbstring sudo apt-get
- Spring AOP技术(基于AspectJ)的Annotation开发
- [二分答案 2-SAT验证 前后缀优化建图] Codeforces 587D #326 (Div. 1) D. Duff in Mafia
- 信息系统服务管理 典型试题分析
- 能量获取 Energy
- MySQL limit实现分页(五)
- Java进阶-数据类型
- java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
- HTML标签之音频、视频标签
- 前端之JQuery
- oc 预编译指令