zoukankan      html  css  js  c++  java
  • 【xsy1378】 水题7号 贪心

    题目大意:有$m$组约束关系$(x_i,y_i)$,你要构造一个排列,满足数$x_i$出现在数$y_i$前面,请使得这个排列字典序最小,请输出这个排列。无解请输出-1。

    数据范围:$n,m≤10^5$

    我们把约束关系$(x_i,y_i)$视作从$y_i$连向$x_i$的有向边,于是我们得到了一个有向图,无解情况下该图会存在环。

    我们对这个有向图进行拓扑排序即可,只不过每次出队的点是当前队列中编号最大的点。

    我们开一个数组$ans$,记$ans_i$表示第i次出队的点的编号。

    若原图中存在环,显然$|ans|≠n$,我们可以通过该性质判断是否有解。

    否则倒着输出$ans$数组即可。

    关于正确性可以这么理解:当第$x$个点出队时,所有依赖于该点的点都出队了,且当前编号大于它的点都出队了。

     1 #include<bits/stdc++.h>
     2 #define M 100005
     3 using namespace std;
     4 
     5 vector<int> v[M];
     6 int n,m,vis[M]={0};
     7 int ans[M]={0},in[M]={0},cnt=0;
     8 priority_queue<int> q;
     9 int Main(){
    10     memset(in,0,sizeof(in));
    11     memset(ans,0,sizeof(ans)); cnt=0;
    12     for(int i=0;i<M;i++) v[i].clear();
    13     scanf("%d%d",&n,&m);
    14     for(int i=1;i<=m;i++){
    15         int x,y; scanf("%d%d",&x,&y);
    16         v[y].push_back(x); in[x]++;
    17     }
    18     for(int i=1;i<=n;i++) if(in[i]==0) q.push(i);
    19     while(!q.empty()){
    20         int u=q.top(); q.pop();
    21         ans[++cnt]=u;
    22         int siz=v[u].size();
    23         for(int i=0;i<siz;i++){
    24             int V=v[u][i];
    25             in[V]--;
    26             if(in[V]==0) q.push(V);
    27         }
    28     }
    29     if(n!=cnt){
    30         printf("Impossible!
    ");
    31         return 0;
    32     }
    33     for(int i=n;i;i--) printf("%d ",ans[i]);
    34 }
    35 int main(){
    36     int t; cin>>t;
    37     while(t--) Main();
    38 }

     

     

  • 相关阅读:
    sleep和wait区别
    java学习路线图
    screen实现关闭ssh之后继续运行代码
    linux截取字符串的多种方法
    如何用Maven创建web项目(具体步骤)
    Failed to read candidate component class包冲突解决方法
    hadoop参数配置
    How to solve java.net.SocketTimeoutException:60000millis problem in HDFS
    win8style布局
    signalR的一些细节
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/10478738.html
Copyright © 2011-2022 走看看