转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
题目:给出一个n*m的矩阵,问是否 能改变列的顺序,使得每一行都非递减(其中-1表示可以作为任何一个数)
由于范围比较大,虽然是比较明显的拓扑排序,但是建图比较麻烦
不可能两两比较然后建图,而且可能出现大量的相同的数字
做法是加入冗余结点,对于每一行我们来建图,排序之后,对于相同的一系列加入一个冗余结点,通过冗余结点来指向关系
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<set>
#include<string>
#include<queue>
#define inf 1000000005
#define M 40
#define N 100005
#define maxn 300005
#define eps 1e-8
#define zero(a) fabs(a)<eps
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define LL long long
#define MOD 1000000007
#define lson step<<1
#define rson step<<1|1
#define sqr(a) ((a)*(a))
#define Key_value ch[ch[root][1]][0]
#define test puts("OK");
#define pi acos(-1.0)
#define lowbit(x) ((-(x))&(x))
#define HASH1 1331
#define HASH2 10001
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
struct Node{
int val,idx;
bool operator<(const Node n)const{
return val<n.val;
}
}a[N];
int n,m,in[N*2],cnt;
vector<int>edge[N*2];
queue<int>que;
void add(int u,int v){
in[v]++;
edge[u].pb(v);
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&a[j].val);
a[j].idx=j;
}
sort(a,a+m);
for(int j=0;j<m;j++){
if(a[j].val==-1) continue;
if(!j||a[j].val!=a[j-1].val) cnt++;
add(a[j].idx,m+cnt+1); //本身指向比自己大的
add(m+cnt,a[j].idx); //比自己小的指向自己
}
cnt++;
}
for(int i=0;i<m+cnt;i++)
if(!in[i])
que.push(i);
int ans[N],tot=0;
while(!que.empty()){
int u=que.front();que.pop();
if(u<m)
ans[tot++]=u;
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i];
in[v]--;
if(!in[v])
que.push(v);
}
}
if(tot<m) puts("-1");
else{
for(int i=0;i<m;i++)
cout<<ans[i]+1<<(i==m-1?"\n":" ");
}
return 0;
}