萌新妹子简单二分60pts求助
查看原帖
萌新妹子简单二分60pts求助
227728
冰糖鸽子TJ鸽子协会楼主2021/8/9 20:57

RT,WA了3,7,8,9kk

就是二分+黑白染色,输出出来答案小了,小的不多,目测二分没问题。


// Problem: P1525 [NOIP2010 提高组] 关押罪犯
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1525
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define M 200005
#define mid ((l+r)/2)
int n,l,r,m,U,V,W,ans=10000008,vis[M]; //vis+记录颜色的功能,为了判断有没有dfs过所以颜色是1/2
struct node
{int s,t,v;}rd[M];//存边
vector<int>road[M]; //vector存图
map<int,int>mp,fmp; //离散化用
bool cmp(node A,node B) {return A.v<B.v;} //排序用
int dfsl(int x)
{
	for(int i=0;i<road[x].size();i++) if(vis[road[x][i]]==vis[x]) return 1; //如果有染色冲突
	for(int i=0;i<road[x].size();i++) {
	 if(!vis[road[x][i]])
	  {
	  	vis[road[x][i]]=3-vis[x];
	  	if(dfsl(road[x][i])) return 1;
	  }
	}
	//上面七行往下dfs,如果有不能黑白染色的就返回不可以
	return 0;
}
bool check(int x)
{
	memset(vis,0,sizeof(vis)); int rrt;
	for(int i=1;i<=n;i++) road[i].clear();
	//上面两行初始化
	for(int i=1;i<=m;i++)
	{
	    if(rd[i].v>x)
		{
			road[rd[i].s].push_back(rd[i].t);
			road[rd[i].t].push_back(rd[i].s);
			rrt=rd[i].s;
		}
	}
	//上面九行建图
	vis[rrt]=1; if(dfsl(rrt)) return 0; //如果这玩意不能黑白染色(不能黑白染色的返回是1不是0)
	return (ans=min(ans,x),1); //返回+更新答案
}
int main()
{
	cin>>n>>m,r=m;
	for(int i=1;i<=m;i++)
	{
		cin>>U>>V>>W;
		rd[i].s=min(U,V),rd[i].t=max(U,V),rd[i].v=W;
	}
	sort(rd+1,rd+m+1,cmp);
	for(int i=1;i<=m;i++) mp[rd[i].v]=i,fmp[i]=rd[i].v;
	for(int i=1;i<=m;i++) rd[i].v=mp[rd[i].v];
	//上面三行离散化
	while(l+2<=r) 
	{
		if(check(mid)) r=mid-1;
		else l=mid+1;
	}
	//上面五行二分
	for(int i=l;i<=r;i++) check(i);
	cout<<fmp[ans]<<endl;
	return 0;
}
2021/8/9 20:57
加载中...