题目链接:
题意:给一个矩阵没行的和和每列的和,问能否还原矩阵,如果可以还原解是否唯一,若唯一输出该矩阵。
思路:设一个源点和汇点,每行的和和源点加边,权值为该行的和,每列的和和汇点加点,权值为该列的和。
每行和每列加边, 权值为k,跑最大流,如果满流(从源点流出的等于流入汇点的)则证明可以还原该矩阵。
判断是否有多节,就dfs搜,看残余网络中是否有环,无环则解唯一。
AC代码:
#include#include #include #include using namespace std;const int oo=1e9;const int mm=4e5+5;const int mn=1e5+5;int node,src,dest,edge;int ver[mm],flow[mm],Next[mm];int head[mn],work[mn],dis[mn],q[mn];int Min(int a,int b){ return a =0; i=Next[i]) if(flow[i]&&dis[v=ver[i]]<0) { dis[q[r++]=v]=dis[u]+1; if(v==dest)return 1; } return 0;}int Dinic_dfs(int u,int exp){ if(u==dest)return exp; for(int &i=work[u],v,tmp; i>=0; i=Next[i]) if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,Min(exp,flow[i])))>0) { flow[i]-=tmp; flow[i^1]+=tmp; return tmp; } return 0;}int Dinic_flow(){ int i,ret=0,delta; while(Dinic_bfs()) { for(i=0; i n && v<=n+m) mp[i][v-n]=k-flow[j]; } } for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { if(j!=1) printf(" "); printf("%d",mp[i][j]); } puts(""); } } } else puts("Impossible"); } return 0;}