• bzoj1059[ZJOI2007] 矩阵游戏


    题目链接:bzoj1059

    题目大意:

    给一个N*N的矩阵,上面有黑白两种颜色的格子。每次可以对该矩阵进行两种操作:行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)列交换操作:选择矩阵的任意行列,交换这两列(即交换对应格子的颜色)游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑色。问有没有方案能实现。


    题解:

    二分图最大匹配

    因为由题意(%hyc)可以发现,实际上是求有没有n个行列互不相同的棋子。于是把行跟列当二分图连边(有点像网络流的经典模型),x行y列有个黑棋子就连x->y。跑个二分图最大匹配就好了。
    然而我一直在往求最大点独立集那方面想..而时间复杂度也根本不允许我建图...

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 41000
    
    struct node
    {
    	int x,y,next;
    }a[maxn*2];int len,first[maxn];
    int n,bf[maxn],ask[maxn],tim;
    void ins(int x,int y)
    {
    	++len;
    	a[len].x=x;a[len].y=y;
    	a[len].next=first[x];first[x]=len;
    }
    int ffind(int x)
    {
    	for (int i=first[x];i!=-1;i=a[i].next)
    	 if (ask[a[i].y]!=tim)
    	 {
    		 int y=a[i].y;
    		 ask[y]=tim;
    		 if (bf[y]==-1 || ffind(bf[y]))
    		 {
    			 bf[y]=x;
    			 return true;
    		 }
    	 }
    	return false;
    }
    bool xyl()
    {
    	memset(ask,0,sizeof(ask));
    	memset(bf,-1,sizeof(bf));
    	for (int i=1;i<=n;i++)
    	{
    		tim++;
    		if (!ffind(i)) return false;
    	}
    	return true;
    }
    int main()
    {
    	int T,i,j,x;
    	scanf("%d",&T);
    	while (T--)
    	{
    		len=tim=0;
    		memset(first,-1,sizeof(first));
    		scanf("%d",&n);
    		for (i=1;i<=n;i++)
    	  	 for (j=1;j<=n;j++)
    		 {
    			scanf("%d",&x);
    			if (x==1) ins(i,j);
    		 }
    		if (xyl()) printf("Yes
    ");
    		else printf("No
    ");
    	}
    	return 0;
    }


  • 相关阅读:
    ArcGIS
    gdal 在 vs2005中的安装
    ArcView ArcEditor ArcInfo区别
    从自行车掉链想到的
    实现带有身份验证的WebService
    研究一下全文索引
    【转】Com和.Net互操作规范
    TDSSNIClient 初始化失败,出现错误 0x7e,状态代码 0x60。
    整理最近新学到的几种sql写法(一)动态“循环”更新表内数据
    整理多个技术点的sql综合应用:(开拓思路,SELECT子句内嵌子查询)
  • 原文地址:https://www.cnblogs.com/Euryale-Rose/p/6527801.html
Copyright © 2020-2023  润新知