「LibreOJ β Round #3」绯色 IOI(抵达)

【题解】

  我们可以发现叶子节点的关联点一定是它的父亲节点,那么我们dfs一遍就可以求出所有节点的关联点,或者判断出无解。

  对于每个点i,它的关联点u的危险度肯定比它连接的其他点vi的危险度小,我们从u向vi连边。

  连边之后我们跑拓扑排序,并且用堆维护当前入度为0的点中编号最小的,以此来让字典序最小。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 #define LL long long
 6 #define rg register
 7 #define N 1000010
 8 using namespace std;
 9 int n,tot,cnt,last[N],last2[N],link[N],in[N],q[N],ans[N];
10 bool vis[N],sol=1;
11 struct edge{int to,pre;}e[N<<1],e2[N<<1];
12 priority_queue<int,vector<int>,greater<int> >f;
13 char buf[20000010],*ptr=buf-1;
14 inline int read(){
15     int f=1,k=0; char c=*++ptr;
16     while(c<'0' || c>'9') c=='-'&&(f=-1), c=*++ptr;
17     while(c<='9' && c>='0') k=k*10+c-'0', c=*++ptr;
18     return k*f;   
19 }
20 void dfs(int x,int fa){
21     if(!sol) return;
22     bool ok=0;
23     for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=fa){
24         dfs(to,x); if(!vis[to]) link[x]=to,vis[to]=1,ok=1;
25     }
26     if(!ok){
27         if(vis[fa]) sol=0;
28         else link[x]=fa,vis[fa]=1;
29     }
30 }
31 void dfs2(int x,int fa){
32     int u=link[x];
33     for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=link[x]){
34         in[to]++;
35         e2[++tot]=(edge){to,last2[u]}; last2[u]=tot;
36 //        printf("%d-->%d\n",u,to);
37     }
38     for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=fa) dfs2(to,x);
39 }
40 int main(){
41 //    freopen("minecraft.in","r",stdin);
42 //    freopen("minecraft.out","w",stdout);
43     fread(buf, 1, sizeof(buf), stdin);
44     n=read();
45     for(rg int i=1;i<n;i++){
46         int u=read(),v=read();
47         e[++tot]=(edge){v,last[u]}; last[u]=tot;
48         e[++tot]=(edge){u,last[v]}; last[v]=tot;
49     }
50     vis[0]=1; 
51     dfs(1,0);
52     if(!sol){puts("-1"); return 0;}
53 //    for(rg int i=1;i<=n;i++) printf("%d ",link[i]); puts("link");
54     tot=0;
55     dfs2(1,0);
56 //    for(rg int i=1;i<=n;i++) printf("%d ",in[i]); puts("in");
57     for(rg int i=1;i<=n;i++)if(!in[i]){
58         f.push(i);
59     }
60     while(f.size()){
61         int now=f.top(); f.pop();
62         ans[++cnt]=now;
63         for(rg int i=last2[now],to;i;i=e2[i].pre){
64             in[to=e2[i].to]--;
65             if(!in[to]) f.push(to);
66         }
67     }
68     for(rg int i=1;i<=n;i++) printf("%d ",ans[i]);
69     return 0;
70 }

 做法二:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 #define LL long long
 6 #define rg register
 7 #define N 500010
 8 using namespace std;
 9 int n,m,tot,ans[N],last[N],deg[N];
10 bool vis[N],cut[N<<1];
11 struct edge{
12     int to,pre;
13 }e[N<<1];
14 priority_queue<int,vector<int>,greater<int> >q;
15 inline int read(){
16     int k=0,f=1; char c=getchar();
17     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
18     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
19     return k*f;
20 }
21 int main(){
22     n=read(); tot=1;
23     if(n==1) return puts("-1"),0;
24     for(rg int i=1;i<n;i++){
25         int u=read(),v=read();
26         e[++tot]=(edge){u,last[v]}; last[v]=tot;
27         e[++tot]=(edge){v,last[u]}; last[u]=tot;
28         deg[u]++; deg[v]++;
29     }
30     for(rg int i=1;i<=n;i++)if(deg[i]<=1) q.push(i),vis[i]=1;
31     for(rg int t=1,now;t<=n;t++){
32         if(!q.size()){puts("-1"); return 0;}
33         ans[t]=now=q.top(); q.pop();
34         for(rg int i=last[now],to;i;i=e[i].pre)if(!cut[i]){
35             to=e[i].to;
36             for(rg int j=last[to],to2;j;j=e[j].pre){
37                 deg[to2=e[j].to]--;
38                 if(!vis[to2]&&deg[to2]<=1) q.push(to2),vis[to2]=1;
39                 cut[j^1]=1;
40             }
41         }
42     }
43     for(rg int i=1;i<=n;i++) printf("%d ",ans[i]);
44     return 0;
45 }

 

posted @ 2018-10-31 15:02  Driver_Lao  阅读(330)  评论(0编辑  收藏  举报