社区讨论

WA on #29 求调

CF587DDuff in Mafia参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@lo2i0nyv
此快照首次捕获于
2023/10/23 14:10
2 年前
此快照最后确认于
2023/10/23 14:10
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,head[N<<1],tot,dfn[N<<1],low[N<<1],st[N<<1],top,num,cnt,a[N],c[N],scc[N<<1],ans[N],k;
bool in[N<<1];
pair<int,int>must[N];
struct edge{
	int nxt,to;
}e[N*20];
inline void add(int a,int b){
	e[++tot]={head[a],b};head[a]=tot;
}
map<int,int>mp;
vector<int>v[N];
#define id(x) (x-1)*4
inline void tarjan(int x){
	dfn[x]=low[x]=++cnt,st[++top]=x,in[x]=1;
	for(int i = head[x],y;i;i=e[i].nxt){
		y=e[i].to;
		if(!dfn[y]){
			tarjan(y);low[x]=min(low[x],low[y]);
		}
		else if(in[y])low[x]=min(low[x],dfn[y]);
	}
	if(low[x]==dfn[x]){
		int y;num++;
		do{
			y=st[top--],scc[y]=num,in[y]=0;
		}while(y^x);
	}
}
inline bool check(int x){
	memset(in,0,sizeof in),memset(head,0,sizeof head),memset(dfn,0,sizeof dfn),memset(low,0,sizeof low),memset(st,0,sizeof st),memset(scc,0,sizeof scc),tot=cnt=num=top=0;
	for(int i = 1;i<=m;i++)if(a[i]>x)add(id(i)+1,id(i)+2);
	for(int i = 1;i<=n;i++){
		for(int j = 0;j<v[i].size();j++){
			add(id(v[i][j])+1,id(v[i][j])+3),add(id(v[i][j])+4,id(v[i][j])+2);
			if(j)add(id(v[i][j-1])+3,id(v[i][j])+3),add(id(v[i][j])+1,id(v[i][j-1])+4);
			if(j!=v[i].size()-1)add(id(v[i][j+1])+4,id(v[i][j])+4),add(id(v[i][j])+3,id(v[i][j+1])+2);
		}
		if(must[i].first){
			add(id(must[i].first)+2,id(must[i].second)+1);add(id(must[i].second)+2,id(must[i].first)+1);
		}
	}
	for(int i = 1;i<=m*4;i++)if(!dfn[i])tarjan(i);
	for(int i = 1;i<=m;i++)if(scc[id(i)+1]==scc[id(i)+2])return 0;
	return 1;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i = 1,x,y;i<=m;i++)scanf("%d%d%d%d",&x,&y,&c[i],&a[i]),v[x].push_back(i),v[y].push_back(i);
	for(int i = 1,maxn,cnt;i<=n;i++){
		must[i].first=must[i].second=0;
		mp.clear();maxn=cnt=0;
		for(int j = 0;j<v[i].size();j++){
			maxn=max(maxn,++mp[c[v[i][j]]]);
			if(mp[c[v[i][j]]]>=2)cnt++;
		}
		if(maxn>2||cnt>=2){
			printf("No");return 0;
		}
		if(cnt==1){
			for(int j = 0;j<v[i].size();j++){
				if(mp[c[v[i][j]]]==2){
					if(!must[i].first)must[i].first=v[i][j];
					else {
						must[i].second=v[i][j];
						break;
					}
				}
			}
		}
	}
	int l=0,r=1e9,mid;
	while(l<=r){
		mid=l+r>>1;
		if(check(mid))r=mid-1;
		else l=mid+1;
	}
	check(r+1);		
	printf("Yes\n%d ",r+1);
	for(int i = 1;i<=m;i++)if(scc[id(i)+1]<scc[id(i)+2])ans[++k]=i;
	printf("%d\n",k);
	for(int i = 1;i<=k;i++)printf("%d ",ans[i]);
	return 0;
}
rt

回复

1 条回复,欢迎继续交流。

正在加载回复...