• Hdu 5093 Battle Ship


    每个海面要么放要么不放,因此可以用二分图匹配, 考虑把同一行内的能互相看到的点放到一个行块里,同一列内能看到的点放到一个列块里,然后每一个行块都可以和该行块里所有海面的列块连边,选了这个行块,就必须选且只选择一个该行块里的一个海面对应的列块。

    #include <iostream>	
    #include <cmath>	
    #include <cstdio>	
    #include <algorithm>
    #include <cstring>	
    #define N 10100
    using namespace std;
    struct edg {
    	int to, nex;
    }e[N];
    char ma[101][101];				
    int n, m, T, n1, n2, cnt, cntx, cnty;
    int flag[N], lin[N], x[101][101], y[101][101], vis[N];
    void add(int f, int t)			
    {
    	e[++cnt].to = t;
    	e[cnt].nex = lin[f];
    	lin[f] = cnt;
    }
    bool dfs(int now)
    {
    	for (int i = lin[now]; i; i = e[i].nex)
    	{
    		int to = e[i].to;
    		if (vis[to]) continue;
    		vis[to] = 1;
    		if (flag[to] == -1 || dfs(flag[to]))
    		{
    			flag[to] = now;
    			return 1;
    		}
    	}
    	return 0;
    }
    void clea()
    {
    	memset(flag, -1, sizeof(flag));
    	memset(e, 0, sizeof(e));
    	memset(lin, 0, sizeof(lin));
    	memset(vis, 0, sizeof(vis));
    	cnt = 0;
    	cntx = cnty = 1;
    }
    int main()
    {
     	scanf("%d", &T);
     	while (T--)
     	{ 
    	 	clea();
    	 	scanf("%d%d", &n, &m);
    	 	char ca  = getchar();;
    	 	for (int i = 1; i <= n; i++, ca = getchar())
    	 		for (int j = 1; j <= m; j++)
    	 			scanf("%c", &ma[i][j]);
    	 	for (int i = 1; i <= n; i++, cntx++)
    	 		for (int j = 1; j <= m; j++)
    	 		{
    	 			if (ma[i][j] == '*')//把属于同一行的数并到一起 
    	 				x[i][j] = cntx;
    	 			if (ma[i][j] == '#')
    	 				++cntx;
    	 		}
    	 	for (int i = 1; i <= m; i++, cnty++)
    	 		for (int j = 1; j <= n; j++)
    	 		{
    	 			if (ma[j][i] == '*')
    	 				y[j][i] = cnty;
    	 			if (ma[j][i] == '#')
    	 				++cnty;
    	 		}
    	 	for (int i = 1; i <= n; i++)
    	 		for (int j = 1; j <= m; j++)
    	 			if (ma[i][j] == '*')
    	 				add(x[i][j], y[i][j]);
    	 	n1 = cntx, n2 = cnty;
    	 	int ans = 0;
    	 	for (int i = 1; i <= n1; i++)
    	 	{
    	 		memset(vis, 0, sizeof(vis));
    	 		if (dfs(i))
    	 			ans++;
    	 	}
    	 	for (int i = 1; i <= n2; i++)
    			if (flag[i]!=-1)
    				printf("%d %d
    ", flag[i], i); 
    	 	printf("%d
    ", ans);
    	}
    	return 0;
    }//
    /*
    1
    4 4
    *ooo
    o###
    **#*
    ooo*
    */
    
  • 相关阅读:
    day 15 小结
    python中的数据类型以及格式化输出
    编程语言简介
    计算机简介
    堆排
    Lock锁
    JVM入门
    Java中反射调用私有方法出现NoSuchMethodException
    1248. 统计「优美子数组」
    注解
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/11655461.html
Copyright © 2020-2023  润新知