2018.08.29 【校内模拟】T2 表格 (虚点建图)(拓扑排序)

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82184609

【描述】

给出一个表格, N 行 M 列,每个格子有一个整数,有些格子是空的。现在需要你来做出一些调整,使得每行都是非降序的。这个调整只能是整列的移动。

【输入】

第一行两个正整数 N 和 M。
接下来 N 行,每行 M 个整数, -1 表示这个格子是空的,其他的整数都在 [0, 10^9]范围,表示格子的数字。

【输出】

若无解,输出 -1;
否则输出任意一个解,即一行 M 个正整数 p1, p2, · · · , pm,表示可以把初始表格的 pi 列,放在新表格的第 i 列,以得到一个合法的表格。

【样例输入 1】

3 3
-1 -1 -1
2 1 2
2 -1 1

【样例输出 1】

2 3 1

【样例输入 2】

2 2
1 2
2 1

【样例输出 2】

-1

【数据规模】

对于 20% 的数据,满足 1 ≤ N ≤ 8, 1 ≤ M ≤ 8。
对于 60% 的数据,满足 1 ≤ N × M ≤ 2 × 10^3。
对于 100% 的数据,满足 1 ≤ N × M ≤ 10^5。


解析:

很有水平的一道题。

像我这种平时网络流建图都是拆点建,一遇到虚点建图的题就不会做了。。。

骗分还一分都没有。。。

详解可能会在下一次大规模补题解的时候补上。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define pc putchar
#define gc getchar
#define cs const
#define st static

inline
ll getint(){
    st ll num;
    st char c;
    st bool f;
    for(f=1,c=gc();!isdigit(c);c=gc())if(c=='-')f=0;
    for(num=0;isdigit(c);c=gc())num=(num<<1)+(num<<3)+(c^48);
    return f?num:-num;
}

inline
void outint(ll a){
    st char ch[32];
    if(a==0)pc('0');
    while(a)ch[++ch[0]]=(a-a/10*10)^48,a/=10;
    while(ch[0])pc(ch[ch[0]--]);
}

pair<int,int> p[100005];
int ans[100005],tot;
bool exist[100005],vis[100005];
int n,m;

int last[300005],nxt[1000005],to[1000005],ecnt;
int in[300005];

int tt;

inline
void addedge(int u,int v){
    nxt[++ecnt]=last[u],last[u]=ecnt;
    to[ecnt]=v;
    ++in[v];
}

inline
bool BFS(){
    queue<int> q;
    for(int re i=m+1;i<=tt;++i){
        if(in[i]==0)q.push(i);
    }
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=true;
        if(u>=1&&u<=m)ans[++tot]=u;
        for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]]){
            --in[v];
            if(in[v]==0)q.push(v);
        }
    }
    for(int re i=1;i<=m;++i){
        if(!exist[i])ans[++tot]=i;
        else if(!vis[i])return false;
    }
    return true;
}


int t;

int main(){
    n=getint();
    tt=m=getint();
    for(int re i=1;i<=n;++i){
        ++tt;
        t=0;
        for(int re j=1;j<=m;++j){
            int k=getint();
            if(k!=-1)p[++t]=make_pair(k,j);
        }
        if(!t||t==1)continue;
        sort(p+1,p+t+1);
        int head=1,tail=1;
        while(tail<=t){
            while(p[tail+1].first==p[tail].first&&tail<t)++tail;
            for(int re j=head;j<=tail;++j){
                exist[p[j].second]=true;
                addedge(tt,p[j].second);
                addedge(p[j].second,tt+1);
            }
            ++tt;
            head=++tail;
        }
    }
    if(!BFS())puts("-1");
    else{
        for(int re i=1;i<=m;++i)outint(ans[i]),pc(' ');
    }
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/82184609