• Jzoj4437 线性代数与逻辑


    不要被标题迷惑了,这是个图论题目。

    我们发现,若Ai,j=1那么显然Xi,j=1,所以y[i]!=y[j]

    这时候就变成了一个类似二分图的图,若Ai,j=1我们将节点i,j连一条边表示i和j不能相等

    我们先对每个节点i拆点成i和i+n,跑一次2sat,若i和i+n可以互达,那么显然无解,否则我们要将所有的点分入两个集合并且使得两个集合大小的乘积尽可能大

    这时候就可以对于每个节点i,dfs一次,将这个节点i加入集合0或者集合1中元素较少那个,那么显然,与i连边的所有的j都要加入另一个,而所有与j相连的节点k。。。以此类推,直到每个节点都被分入集合0或者集合1

    为什么上述方法是可行的?因为如果我们发现这个图是一个二分图,那么显然一次分配过程中,分配进入集合0和集合1的点的个数差不会超过一,所以集合0和集合1

    那么答案就是两个集合大小的乘积

    #include<stdio.h>
    #include<string.h>
    #include<vector>
    using namespace std;
    vector<int> g[2010];
    int n=0,T,st[2010],c[3]; bool vis[2010],A[1010][1010];
    inline int d(int x){ return x<=n?x+n:x-n; }
    int dfs(int x){
    	vis[x]=st[x]=1;
    	if(st[d(x)]) return st[x]=0;
    	for(int i=0,z=g[x].size();i<z;++i)
    		if(!vis[g[x][i]])
    		if(!dfs(g[x][i])) return 0;
    	st[x]=0; return 1;
    }
    void dijk(int x){
    	for(int i=0,v,z=g[x].size();i<z;++i){
    		v=(g[x][i]-1)%n+1;
    		if(!st[v]){ 
    			c[st[v]=st[x]^3]++;
    			dijk(v);
    		}
    	}
    }
    void Init(){
    	memset(vis,0,sizeof vis);
    	for(int i=1;i<2010;++i) g[i].clear();
    	c[1]=c[2]=0; memset(st,0,sizeof st);
    }
    int kmp(){
    	scanf("%d",&n);
    	for(int x,i=1;i<=n;++i)
    		for(int j=1;j<=n;++j){
    			scanf("%d",A[i]+j);
    			if(A[i][j]){
    				g[i].push_back(j+n);
    				g[i+n].push_back(j);
    			}
    		}
    	for(int i=1;i<=n<<1;++i) //检查是否有解
    		if(!vis[i]&& !dfs(i)){
    			puts("-1"); return 0;
    		}
    	for(int i=1;i<=n;++i)//分配点,st[i]=1代表i在集合0,st[i]=2代表在集合1,st[i]=0代表未分配
     		if(!st[i]){
    			if(c[1]>c[2]) st[i]=2; else st[i]=1;
    			c[st[i]]++; dijk(i);
    		}
    	int ans=0;
    	for(int i=1;i<=n;++i) --st[i];
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=n;++j)
    			if(!A[i][j]&&st[i]^st[j]) ans++;
    	printf("%d
    ",ans);
    }
    int main(){ for(scanf("%d",&T);T--;Init()) kmp(); }

  • 相关阅读:
    demo2动态加载显示商品详情页
    demo1 动态显示view或弹框 动态隐藏view或弹框
    ios 继承UITableViewController,更改tableview样式
    ios数组基本用法和排序大全
    demo1 动态显示view或弹框 动态隐藏view或弹框
    ios数组基本用法和排序大全
    爬虫从入门到放弃
    软件测试方法
    熟悉项目需求,要知道产品增删修改了哪些内容,才会更快更准确的在该项目入手。
    速达光耀开发版软件关于360安全卫士杀掉的说明
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477326.html
Copyright © 2020-2023  润新知