ATcoder ABC 352 F - Estimate Order 搜索

很恶心的一个搜索,当然好像不用搜索也能做。

没啥好讲的,一个联通块大小>=2就要搜索找位置,联通块大小等于1的不用搜。

能调出来也是真不容易。

#include<bits/stdc++.h>
#define int long long
#define DB double
using namespace std;
int n,m,tsiz,yinum;
const int N=23;
int fa[N],duo[N][N],in[N],ans[N],yong[N];
int find(int x){return x==fa[x]?fa[x]:fa[x]=find(fa[x]);}
struct tu
{
	int siz,cnt,minn;
	vector<int>id,v;
	set<int>pos;
	friend bool operator <(const tu &a,const tu &b)
	{
		return a.siz>b.siz;
	}
}t[N];
int pan(int hao,int pos)
{
	for(int j=0;j<t[hao].siz;++j)
		if(pos+t[hao].v[j]>n||yong[pos+t[hao].v[j]])return 0;
	return 1;
}
int dfs(int hao)
{
	if(hao==tsiz+1)return 1;
	if(yinum==1&&t[hao].siz==1)
	{
		//cout<<"hello"<<endl;
		for(int i=1;i<=n;++i)
			if(!yong[i])t[hao].pos.insert(i);//,cout<<i<<endl;
		return 1;
	}
	if(yinum>1&&t[hao].siz==1)
	{
		return 1;
	}
	//cout<<"--> "<<hao<<" "<<t[hao].siz<<" "<<t[hao].v[1]<<endl;
	int flag=0;
	for(int i=1;i<=n;++i)
		if(pan(hao,i))
		{
			for(int j=0;j<t[hao].siz;++j)yong[i+t[hao].v[j]]=1;
			
			if(dfs(hao+1))t[hao].pos.insert(i),flag=1;
			for(int j=0;j<t[hao].siz;++j)yong[i+t[hao].v[j]]=0;
		}
	if(flag)return 1;
	else return 0;
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;++i)fa[i]=i,ans[i]=-1;
	for(int i=1,a,b,c;i<=m;++i)scanf("%lld%lld%lld",&a,&b,&c),fa[find(a)]=fa[find(b)],duo[a][b]=c,duo[b][a]=-c;
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			if(i!=k)for(int j=1;j<=n;++j)
				if(j!=i&&j!=k&&duo[i][k]&&duo[k][j])duo[i][j]=duo[i][k]+duo[k][j];//cout<<"-> "<<i<<" "<<j<<endl;
	for(int i=1;i<=n;++i)
	{
		if(in[i])continue;
		++tsiz;
		for(int j=1;j<=n;++j)
			if(find(i)==find(j))
			{
				in[j]=1;
				t[tsiz].siz++;
				//cout<<"-> "<<tsiz<<" "<<j<<" "<<i<<" "<<duo[j][i]<<endl;
				t[tsiz].v.push_back(duo[j][i]);
				t[tsiz].id.push_back(j);
			}
		sort(t[tsiz].v.begin(),t[tsiz].v.end());
		for(int j=t[tsiz].siz-1;j>=0;--j)t[tsiz].v[j]-=t[tsiz].v[0];
	}
	sort(t+1,t+1+tsiz);
	for(int i=1;i<=tsiz;++i)
		if(t[i].siz==1)++yinum;
	
	dfs(1);
	
	for(int i=1;i<=tsiz;++i)
		if(t[i].siz>1)
		{
			for(int j=0;j<t[i].siz;++j)
			{
				int flag=1;
				for(int k=0;k<t[i].siz;++k)
					if(duo[t[i].id[j]][t[i].id[k]]>0)
					{
						flag=0;
						break;
					}
				if(flag)
				{
					t[i].minn=t[i].id[j];
					//cout<<"-> "<<i<<" "<<t[i].id[j]<<endl;
					break;
				}
			}
			
			if(t[i].pos.size()==1)
			{
				int begpos=*t[i].pos.begin();
				for(int j=0;j<t[i].siz;++j)ans[t[i].id[j]]=begpos+duo[t[i].id[j]][t[i].minn];
			}
		}
		else
		{
		//cout<<"-  "<<i<<endl;
			if(yinum==1&&t[i].pos.size()==1)
			{
				ans[t[i].id[0]]=*t[i].pos.begin();
			}
		}
	for(int i=1;i<=n;++i)printf("%lld ",ans[i]);
	return 0;
}
/*
5 2
2 3 4
5 4 2
*/
posted @ 2024-05-07 21:50  wljss  阅读(32)  评论(0编辑  收藏  举报