这个题跟4975基本一样的,在这之前一直TLE。昨天做4975的时候才发现建图的时候连边的顺序对时间有比较大的影响,所以改了下,然后这里可以用2种方法找环,一种DP,一种DFS。唉,想不到那天是因为建图的顺序导致的TLE;
代码(DFS找环):
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int inf=1<<29;
const int maxn=1010;
const int maxm=6e5;
struct Edge
{
int u;
int v;
int f;
int nxt;
Edge(){}
Edge(int su,int sv,int sf,int snxt):u(su),v(sv),f(sf),nxt(snxt){}
}E[maxm];
int n,m,k,row[510],col[510],sumr,sumc;
int e,st,des,head[maxn],level[maxn],result[501][501];
bool vis[maxn];
int q[maxn];
void AddEdge(int u,int v,int f)
{
E[e]=Edge(u,v,f,head[u]);
head[u]=e++;
E[e]=Edge(v,u,0,head[v]);
head[v]=e++;
}
void Build()
{
e=st=0,des=n+m+1;
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
AddEdge(i,n+j,k);
for(int i=1;i<=n;i++)
AddEdge(st,i,row[i]);
for(int i=1;i<=m;i++)
AddEdge(n+i,des,col[i]);
}
bool BFS()
{
memset(level,0,sizeof(level));
level[st]=1;
int pre=0,last=1;
q[pre]=st;
while(pre<last)
{
int u=q[pre++];
for(int i=head[u];i!=-1;i=E[i].nxt)
if(E[i].f&&!level[E[i].v])
{
level[E[i].v]=level[u]+1;
q[last++]=E[i].v;
if(E[i].v==des)
return level[E[i].v];
}
}
return level[des];
}
int DFS(int u,int maxf)
{
if(u==des||!maxf)
return maxf;
int f=0;
for(int i=head[u];i!=-1;i=E[i].nxt)
if(E[i].f&&level[E[i].v]==level[u]+1)
{
int t=DFS(E[i].v,min(E[i].f,maxf-f));
if(t>0)
{
E[i].f-=t;
E[i^1].f+=t;
f+=t;
if(f==maxf)
break;
}
else
level[E[i].v]=0;
}
return f;
}
int maxflow()
{
int ans=0;
while(BFS())
ans+=DFS(st,inf);
return ans;
}
bool dfs(int u,int f)
{
vis[u]=1;
for(int i=head[u];i!=-1;i=E[i].nxt)
if(E[i].f)
{
if(!vis[E[i].v])
{
if(dfs(E[i].v,u))
return true;
}
else if(E[i].v!=f)
return true;
}
vis[u]=0;
return false;
}
void solve(int sumr,int sumc)
{
if(sumr!=sumc)
{
printf("Impossible\n");
return;
}
Build();
int ans=maxflow();
if(ans!=sumc)
{
printf("Impossible\n");
return;
}
memset(vis,0,sizeof(vis));
bool is=false;
for(int i=1;i<=n;i++)
if(dfs(i,-1))
is=true;
if(!is)
{
printf("Unique\n");
for(int i=0;i<n*m*2;i+=2)
result[E[i].u][E[i].v-n]=E[i^1].f;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
printf("%d%c",result[i][j],j==m?'\n':' ');
}
else
printf("Not Unique\n");
}
inline bool read(int &n)
{
int x = 0, tmp = 1;
char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
int main()
{
int T,cas=1;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
sumr=sumc=0;
for(int i=1;i<=n;i++)
{
read(row[i]);
sumr+=row[i];
}
for(int i=1;i<=m;i++)
{
read(col[i]);
sumc+=col[i];
}
solve(sumr,sumc);
}
return 0;
}
代码(DP找环):
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int inf=1<<29;
const int maxn=1010;
const int maxm=6e5;
struct Edge
{
int u;
int v;
int f;
int nxt;
Edge(){}
Edge(int su,int sv,int sf,int snxt):u(su),v(sv),f(sf),nxt(snxt){}
}E[maxm];
int n,m,K,row[510],col[510],sumr,sumc;
int e,st,des,head[maxn],level[maxn],w[maxn][maxn];
bool vis[maxn][maxn];
int q[maxn],result[maxn][maxn];
void AddEdge(int u,int v,int f)
{
E[e]=Edge(u,v,f,head[u]);
head[u]=e++;
E[e]=Edge(v,u,0,head[v]);
head[v]=e++;
}
void Build()
{
e=st=0,des=n+m+1;
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
AddEdge(i,n+j,K);
for(int i=1;i<=n;i++)
AddEdge(st,i,row[i]);
for(int i=1;i<=m;i++)
AddEdge(n+i,des,col[i]);
}
bool BFS()
{
memset(level,0,sizeof(level));
level[st]=1;
int pre=0,last=1;
q[pre]=st;
while(pre<last)
{
int u=q[pre++];
for(int i=head[u];i!=-1;i=E[i].nxt)
if(E[i].f&&!level[E[i].v])
{
level[E[i].v]=level[u]+1;
q[last++]=E[i].v;
if(E[i].v==des)
return level[E[i].v];
}
}
return level[des];
}
int DFS(int u,int maxf)
{
if(u==des||!maxf)
return maxf;
int f=0;
for(int i=head[u];i!=-1;i=E[i].nxt)
if(E[i].f&&level[E[i].v]==level[u]+1)
{
int t=DFS(E[i].v,min(E[i].f,maxf-f));
if(t>0)
{
E[i].f-=t;
E[i^1].f+=t;
f+=t;
if(f==maxf)
break;
}
else
level[E[i].v]=0;
}
return f;
}
int maxflow()
{
int ans=0;
while(BFS())
ans+=DFS(st,inf);
return ans;
}
void solve(int sumr,int sumc)
{
if(sumr!=sumc)
{
printf("Impossible\n");
return;
}
Build();
int ans=maxflow();
if(ans!=sumc)
{
printf("Impossible\n");
return;
}
memset(vis,0,sizeof(vis));
bool is=false;
int up=n*m*2;
for(int i=0;i<up;i+=2)
w[E[i].u][E[i].v-n]=E[i].f;
for(int i=1;i<=n&&!is;i++)
{
for(int j=1;j<=m&&!is;j++)
for(int k=j+1;k<=m;k++)
{
bool s1=false,s2=false;
if(w[i][j]<K&&w[i][k])
{
if(vis[k][j])
{
is=true;
break;
}
s1=true;
}
if(w[i][j]&&w[i][k]<K)
{
if(vis[j][k])
{
is=true;
break;
}
s2=true;
}
if(s1)
vis[j][k]=1;
if(s2)
vis[k][j]=1;
}
}
if(!is)
{
printf("Unique\n");
for(int i=0;i<n*m*2;i+=2)
result[E[i].u][E[i].v-n]=E[i^1].f;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
printf("%d%c",result[i][j],j==m?'\n':' ');
}
else
printf("Not Unique\n");
}
inline bool read(int &n)
{
int x = 0, tmp = 1;
char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&K)!=EOF)
{
sumr=sumc=0;