思路:拓扑排序,若每一行都逐个建边需要O(n*m*m),那么先排序,通过定义“冗余点”进行统一建边,就变成O(n*m*log(m))了。
#include <bits/stdc++.h>
# define pb push_back
using namespace std;
const int maxn = 2e5+300;
int flag=1, n, m, a[maxn], in[maxn], q[maxn];
int ans[maxn], cnt=0;
vector<int>v[maxn];
struct node{int val, id;}e[maxn];
bool cmp(node x, node y){return x.val < y.val;}
void add(int x, int y)
{
v[x].pb(y);
++in[y];
}
void toposort()
{
int l=0, r=0, icount=0;
for(int i=1; i<cnt+m; ++i)
if(in[i] == 0)
q[r++] = i;
while(l<r)
{
int u = q[l++];
if(u <= m) ans[icount++] = u;
for(auto j : v[u])
if(--in[j] == 0)
q[r++] = j;
}
if(icount < m) flag = 0;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=m; ++j)
scanf("%d",&e[j].val),e[j].id=j;
sort(e+1, e+1+m, cmp);
for(int j=1; j<=m; ++j)
{
if(e[j].val == -1) continue;
if(j==1||e[j].val != e[j-1].val) ++cnt;
add(e[j].id, cnt+m+1);
add(cnt+m, e[j].id);
}
++cnt;
}
toposort();
if(!flag) puts("-1");
else
for(int i=0; i<m; ++i)
printf("%d ",ans[i]);
return 0;
}