Cover
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 346 Accepted Submission(s): 112
Special Judge
Problem Description
You have an n∗n matrix.Every grid has a color.Now there are two types of operating:
L x y: for(int i=1;i<=n;i++)color[i][x]=y;
H x y:for(int i=1;i<=n;i++)color[x][i]=y;
Now give you the initial matrix and the goal matrix.There are m operatings.Put in order to arrange operatings,so that the initial matrix will be the goal matrix after doing these operatings
It's guaranteed that there exists solution.
Input
There are multiple test cases,first line has an integer T
For each case:
First line has two integer n , m
Then n lines,every line has n integers,describe the initial matrix
Then n lines,every line has n integers,describe the goal matrix
Then m lines,every line describe an operating
1≤color[i][j]≤n
T=5
1≤n≤100
1≤m≤500
Output
For each case,print a line include m integers.The i-th integer x show that the rank of x-th operating is i
Sample Input
1 3 5 2 2 1 2 3 3 2 1 3 3 3 3 3 3 3 3 3 3 H 2 3 L 2 2 H 3 3 H 1 3 L 2 3
Sample Output
5 2 4 3 1
题意:给出n*n的初始矩阵和n*n的目标矩阵,m次操作,要求你对m次操作排序使初始矩阵转换为目标矩阵,题目保证有解;
分析:对于目标矩阵,最后一次操作一定使矩阵转换成为目标矩阵,并且这个关键操作之后的矩阵不会被之前的操作影响到,那么我们每次就可以倒着来找这个操作。对于每个操作,我们找到它影响到哪些点,记录入度,如果这个操作之后某个点与目标矩阵上的点不同则添加一个入度,入度为0的操作一定为最后一次操作,从这个操作依次向前递推,拓扑排序得到答案。
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
#define maxn 100005
int color[105][105];
int vis[105][105];
int in[505];
int x[505];
int y[505];
char s[505][3];
int ans[505];
int que[505];
int n,m;
int e_max;
int fir[maxn],u[maxn],v[maxn],nex[maxn];
void init()
{
memset(vis,0,sizeof vis);
memset(fir,-1,sizeof fir);
e_max=0;
}
void add_edge(int s,int t)
{
int e=e_max++;
u[e]=s;
v[e]=t;
nex[e]=fir[s];
fir[s]=e;
}
int main()
{
int TAT;
scanf("%d",&TAT);
while(TAT--)
{
scanf("%d%d",&n,&m);
memset(in,0,sizeof in);
init();
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d",&color[i][j]);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d",&color[i][j]);
for(int i=1; i<=m; i++)
{
scanf("%s%d%d",s[i],&x[i],&y[i]);
if(s[i][0]=='L')
{
for(int j=1; j<=n; j++)
if(color[j][x[i]]!=y[i]) add_edge(j*n+x[i],i),in[i]++;
}
else
{
for(int j=1; j<=n; j++)
if(color[x[i]][j]!=y[i]) add_edge(x[i]*n+j,i),in[i]++;
}
}
int f=0;
int r=-1;
for(int i=1; i<=m; i++)
if(in[i]==0) que[++r]=i,in[i]--;
int line=0;
while(f<=r)
{
int k=que[f++];
ans[line++]=k;
if(s[k][0]=='L')
{
for(int i=1; i<=n; i++)
{
if(vis[i][x[k]]) continue;
for(int j=fir[i*n+x[k]];~j;j=nex[j])
{
int e=v[j];
in[e]--;
if(in[e]==0) que[++r]=e,in[e]--;
}
vis[i][x[k]]=1;
}
}
else
{
for(int i=1; i<=n; i++)
{
if(vis[x[k]][i]) continue;
for(int j=fir[x[k]*n+i];~j;j=nex[j])
{
int e=v[j];
in[e]--;
if(in[e]==0) que[++r]=e,in[e]--;
}
vis[x[k]][i]=1;
}
}
}
for(int i=line-1; i>=0; i--)
{
printf("%d",ans[i]);
if(i) printf(" ");
else puts("");
}
}
return 0;
}