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
*/