• HDU [P2819] swap


    二分图行列匹配+输出路径

    经典题,当且仅当一行匹配一列的时候,符合题意。
    本题的难点在于如何输出路径,我们发现这个移动的过程就是将所有匹配选择排序,在选择排序时输出路径即可

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int init(){
    	int rv=0,fh=1;
    	char c=getchar();
    	while(c<'0'||c>'9'){
    		if(c=='-') fh=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9'){
    		rv=(rv<<1)+(rv<<3)+c-'0';
    		c=getchar();
    	}
    	return fh*rv;
    }
    int n,ma[105][105],g[105][105],match[105];
    bool f[105];
    bool hungarian(int u){
    	for(int i=1;i<=g[u][0];i++){
    		int v=g[u][i];
    		if(!f[v]){
    			f[v]=1;
    			if(!match[v]||hungarian(match[v])){
    				match[v]=u;
    				return 1;
    			}
    		}
    	}
    	return 0;
    }
    int main(){
    	while(~scanf("%d",&n)){
    		memset(ma,0,sizeof(ma));
    		memset(match,0,sizeof(match));
    		memset(g,0,sizeof(g));
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=n;j++){
    				ma[i][j]=init();
    				if(ma[i][j]) g[i][++g[i][0]]=j;
    			}
    		}
    		int ans=0;
    		for(int i=1;i<=n;i++){
    			memset(f,0,sizeof(f));
    			if(hungarian(i)) ans++;
    		}
    		if(ans!=n) printf("-1
    ");
    		else{	
    			int cnt=0;
    			int p1[105],p2[105];
    			memset(p1,0,sizeof(p1));
    			memset(p2,0,sizeof(p2));
    			for(int i=1;i<=n;i++){
    				int k=i;
    				for(int j=i;j<=n;j++){
    					if(match[j]<match[k]){
    						k=j;
    					}
    				}
    				if(k!=i){
    					cnt++;
    					p1[cnt]=i;p2[cnt]=k;
    					swap(match[i],match[k]);
    				}
    			}
    			printf("%d
    ",cnt);
    			for(int i=1;i<=cnt;i++){
    				printf("C %d %d
    ",p1[i],p2[i]);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Generator函数介绍
    C语言基础三
    C语言基础二
    C语言基础一
    node——路由控制
    Node.js_HTTP模块
    node_Express安装及检验
    conda Pyhon版本切换
    JAVA泛型里面各值代表的意义
    jq实现表格多行列复制
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8287190.html
Copyright © 2020-2023  润新知