• 1059: [ZJOI2007]矩阵游戏


    1059: [ZJOI2007]矩阵游戏

    链接

    思路:

      可以在对角线上填满的条件是,每一行,每一列,都要有一个数字。所以把列看成一排点,行看成一排点。二分图匹配,要求匹配数是n,即全匹配成功。

    代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cctype>
     5  
     6 using namespace std;
     7 
     8 const int N = 510; // 两倍空间! 
     9 const int INF = 1e9;
    10 struct Edge{
    11     int to,nxt,c;
    12     Edge() {}
    13     Edge(int x,int y,int z) {to = x;c = y;nxt = z;}
    14 }e[100100];
    15 int head[N],dis[N],cur[N],q[100100];
    16 int S,T,tot,L,R;
    17 
    18 inline int read() {
    19     int x = 0,f = 1;char ch = getchar();
    20     for (; !isdigit(ch); ch=getchar()) if(ch=='-') f = -1;
    21     for (; isdigit(ch); ch=getchar()) x = x*10+ch-'0';
    22     return x * f;
    23 }
    24 
    25 void init() {
    26     tot = 1;
    27     memset(head,0,sizeof(head));
    28 }
    29 void add_edge(int u,int v,int w) {
    30     e[++tot] = Edge(v,w,head[u]);head[u] = tot;
    31     e[++tot] = Edge(u,0,head[v]);head[v] = tot;
    32 }
    33 bool bfs() {
    34     for (int i=1; i<=T; ++i) cur[i] = head[i],dis[i] = -1;
    35     L = 1;R = 0;
    36     q[++R] = S;
    37     dis[S] = 1;
    38     while (L <= R) {
    39         int u = q[L++];
    40         for (int i=head[u]; i; i=e[i].nxt) {
    41             int v = e[i].to;
    42             if (dis[v] == -1 && e[i].c > 0) {
    43                 dis[v] = dis[u] + 1;
    44                 q[++R] = v;
    45                 if (v==T) return true;
    46             }
    47         }
    48     }
    49     return false;
    50 }
    51 int dfs(int u,int flow) {
    52     if (u == T) return flow;
    53     int used = 0,tmp;
    54     for (int &i=cur[u]; i; i=e[i].nxt) {
    55         int v = e[i].to;
    56         if (dis[v] == dis[u] + 1 && e[i].c > 0) {
    57             tmp = dfs(v,min(e[i].c,flow-used));
    58             if (tmp) {
    59                 e[i].c -= tmp;e[i^1].c += tmp;
    60                 used += tmp;
    61                 if (used == flow) break;
    62             }
    63         }
    64     }
    65     if (used != flow) dis[u] = -1;
    66     return used;
    67 }
    68 int dinic() {
    69     int ans = 0;
    70     while (bfs()) ans += dfs(S,INF);
    71     return ans;
    72 }
    73 int main() {
    74     int Case = read(); // 不要设成T 
    75     while (Case--) {
    76         init();
    77         int n = read();
    78         S = n+n+1,T = n+n+2;
    79         for (int i=1; i<=n; ++i) 
    80             for (int j=1; j<=n; ++j) {
    81                 int a = read();
    82                 if (a) add_edge(i,j+n,1);
    83             }
    84         for (int i=1; i<=n; ++i) 
    85             add_edge(S,i,1),add_edge(i+n,T,1);
    86         int ans = dinic();
    87         if (ans==n) puts("Yes");
    88         else puts("No");
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    Qt ini文件
    Qt我的文档 桌面路径
    windows zlib库编译步骤
    环形缓冲区
    openssl生成随机数
    怎样安装Scrapy
    CentOS7怎样安装GoAccess1.3
    Docker创建数据卷容器
    Docker创建数据卷
    Docker创建容器
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8987210.html
Copyright © 2020-2023  润新知