• 「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
    ",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 }
  • 相关阅读:
    2014.5.20知识点学习:void及void指针含义的深刻解析(转载)
    2014.5.20知识点学习:void与void*(转载)
    2014.5.19知识点学习:上下文切换
    编写“全选”按钮来操作大量复选框
    排序算法(冒泡排序,选择排序,插入排序,快速排序)
    算法基础
    Git &GitHub
    flask 上下文管理 &源码剖析
    rest-framework框架的基本组件
    Django的FBV和CB
  • 原文地址:https://www.cnblogs.com/DriverLao/p/9883201.html
Copyright © 2020-2023  润新知