暴力+细节分情况讨论——cf1343F

/*
先定一个结尾:只出现一次的都可以当成结尾,然后把结尾所在的集合影响删掉,继续往前找 
找完一整个序列后还要再和给定的序列比较一下看是不是满足要求 
注意前两个数要特判,第一个数肯定比第二个数出现次数少 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 505
 
int vis[N],n,cnt[N];
set<int>s[N],ss[N];
vector<int>ans;
 
struct Node{
    int c,f,id;//出现次数,在上一个数组中是否出现过 
}p[N];
int cmp(Node a,Node b){
    if(a.c==b.c)return a.f>b.f;
    return a.c<b.c;
}
int pos;
int solve(int end){
    pos=0;
    ans.clear();
    memset(p,0,sizeof p);
    memset(vis,0,sizeof vis);
    int num=end,now;
    for(int i=1;i<=n;i++)
        p[i].c=cnt[i],p[i].f=0,p[i].id=i;
    ans.push_back(num);p[num].c=100000;
    
    for(int i=2;i<=n;i++)
        if(s[i].find(num)!=s[i].end())
            now=i,vis[i]=1;
    
    ss[++pos]=s[now];        
    for(auto x:s[now])p[x].c--,p[x].f=1;
    
    for(int i=1;i<=n-2;i++){
        sort(p+1,p+1+n,cmp); //按出现次数排序
        int tmp[N];
        for(int j=1;j<=n;j++)tmp[p[j].id]=j; 
        
        if(p[1].c!=1)return 0;
        if(p[1].f==0)return 0;
        num=p[1].id;
        ans.push_back(num);p[tmp[num]].c=100000;
        
        now=-1; 
        for(int j=2;j<=n;j++)
            if(!vis[j] && s[j].find(num)!=s[j].end())
                now=j,vis[j]=1;
        if(now==-1)return 0;
        
        for(int j=1;j<=n;j++)p[j].f=0;
        for(auto x:s[now])p[tmp[x]].c--,p[tmp[x]].f=1;
    }
    
    for(int i=1;i<=n;i++)
        if(p[i].c==0)ans.push_back(p[i].id);
    if(ans.size()!=n)return 0;
    int i=0,j=ans.size()-1;
    while(i<j)
        swap(ans[i],ans[j]),i++,j--;
    if(cnt[ans[0]]>cnt[ans[1]])swap(ans[0],ans[1]);
    
    if(ans.size()==n)return 1;
    
    for(int i=2;i<=n;i++){
        set<int>t;
        for(int j=i-ss[i].size()+1;j<=i-1;j++)
            t.insert(ans[j]);
        if(t!=ss[i])return 0;
    }
    return 0;
}
 
int main(){
    int t;cin>>t;
    while(t--){
        memset(cnt,0,sizeof cnt);
        cin>>n;
        for(int i=1;i<=n;i++)s[i].clear();
        
        for(int i=2;i<=n;i++){
            int k,x;scanf("%d",&k);
            while(k--){
                scanf("%d",&x);
                s[i].insert(x);
                cnt[x]++;
            }
        }
        
        for(int i=1;i<=n;i++)if(cnt[i]==1){
            int res=solve(i);
            if(res)break;
        }
        
        for(int i=0;i<ans.size();i++)
            cout<<ans[i]<<" ";
            puts("");
    }
} 

 

posted on 2020-04-22 16:56  zsben  阅读(177)  评论(0)    收藏  举报

导航