JZOJ 5443. 【NOIP2017提高A组冲刺11.2】字典序
生活随笔
收集整理的這篇文章主要介紹了
JZOJ 5443. 【NOIP2017提高A组冲刺11.2】字典序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
你需要構造一個1~n的排列,使得它滿足m個條件,每個條件形如(ai,bi),表示ai必須在bi前面。在此基礎上,你需要使它的字典序最小。
Input
第一行兩個正整數n,m。接下來m行每行兩個數ai,bi。
Output
輸出一行n個整數表示答案。如果不存在這樣的排列,輸出-1。
Sample Input
5 4
5 4
5 3
4 2
3 2
Sample Output
1 5 3 4 2
Data Constraint
對于20%的數據,n,m<=10。
對于40%的數據,n,m<=200。
對于60%的數據,n,m<=1000。
對于100%的數據,n,m<=100000。
Solution
這題比較簡單,若 Ai 要排在 Bi 前面,就 Ai 向 Bi 連一條有向邊,這樣就構成一個 DAG 。
那么做一遍拓撲排序,用一個小根堆存著,每次取最小,再把入度為零的點加入堆中即可。
時間復雜度 O(N?log?N) 。
Code
#include<cstdio> #include<queue> using namespace std; const int N=1e5+1; priority_queue<int,vector<int>,greater<int> >q; int tot; int ans[N]; int first[N],next[N],en[N],d[N]; inline int read() {int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w; } inline void write(int x) {if(x>9) write(x/10);putchar(x%10+'0'); } inline void insert(int x,int y) {next[++tot]=first[x];first[x]=tot;en[tot]=y;d[y]++; } int main() {int n=read(),m=read();while(m--){int x=read(),y=read();insert(x,y);}for(int i=1;i<=n;i++)if(!d[i]) q.push(i);if(q.empty()) return 0&printf("-1");while(!q.empty()){int x=q.top();q.pop();ans[++ans[0]]=x;for(int i=first[x];i;i=next[i])if(!--d[en[i]]) q.push(en[i]);}if(ans[0]<n) return 0&printf("-1");for(int i=1;i<=n;i++) write(ans[i]),putchar(' ');return 0; }總結
以上是生活随笔為你收集整理的JZOJ 5443. 【NOIP2017提高A组冲刺11.2】字典序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 5441. 【NOIP2017
- 下一篇: O(N) 求 1~N 逆元 模板及证明