• HDU


    Tom and Jerry are playing a game with tubes and pearls. The rule of the game is:

    1) Tom and Jerry come up together with a number K.

    2) Tom provides N tubes. Within each tube, there are several pearls. The number of pearls in each tube is at least 1 and at most N.

    3) Jerry puts some more pearls into each tube. The number of pearls put into each tube has to be either 0 or a positive multiple of K. After that Jerry organizes these tubes in the order that the first tube has exact one pearl, the 2nd tube has exact 2 pearls, …, the Nth tube has exact N pearls.

    4) If Jerry succeeds, he wins the game, otherwise Tom wins.

    Write a program to determine who wins the game according to a given N, K and initial number of pearls in each tube. If Tom wins the game, output “Tom”, otherwise, output “Jerry”.

    Input

    The first line contains an integer M (M<=500), then M games follow. For each game, the first line contains 2 integers, N and K (1 <= N <= 100, 1 <= K <= N), and the second line contains N integers presenting the number of pearls in each tube.

    Output

    For each game, output a line containing either “Tom” or “Jerry”.

    Sample Input

    2 
    5 1 
    1 2 3 4 5 
    6 2 
    1 2 3 4 5 5 

    Sample Output

    Jerry 
    Tom 

    题解:

    网络流嘛,重在建模。我们可以把行中和列中相连或者中间隔有 ‘o’ 的 ‘*’ 点看做一个集合。分别按行和按列扫一遍得到行方向和列方向上的集合,并用boardx[][]和boardy[][]分别存储图中点所属的行列集合编号,然后我们就可以用超级原点和超级汇点分别连接boardx,boardy中的集合,如果一个点在boardx和boardy中都属于集合,代表存在行集合和列集合交叉点则可以建立行集合和列集合之间的边。这里的边flow皆为1。

    代码:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <vector>
    
    using namespace std;
    
    const int MAXN = 55;
    const int INF = 0x3f3f3f3f;
    
    struct Edge{
    	int flow,to,rev;
    	Edge(){}
    	Edge(int a,int b,int c):to(a),flow(b),rev(c){}
    };
    
    vector<Edge> E[MAXN*MAXN];
    
    void Add(int from,int to,int flow){
    	E[from].push_back(Edge(to,1,E[to].size()));
    	E[to].push_back(Edge(from,0,E[from].size()-1));
    }
    
    int boardx[MAXN][MAXN],boardy[MAXN][MAXN];
    
    char map[MAXN][MAXN];
    
    inline void init(){
    	memset(boardx,0,sizeof boardx);
    	memset(boardy,0,sizeof boardy);
    }
    
    int deep[MAXN*MAXN];
    
    bool BFS(int from,int to){
    	memset(deep,-1,sizeof deep);
    	deep[from] = 0;
    	queue<int> Q;
    	Q.push(from);
    	while(!Q.empty()){
    		int t = Q.front();
    		Q.pop();
    		for(int i=0 ; i<E[t].size() ; ++i){
    			Edge& e = E[t][i];
    			if(e.flow > 0 && deep[e.to] == -1){
    				deep[e.to] = deep[t] + 1;
    				Q.push(e.to);
    			}
    		}
    	}
    	return deep[to] != -1;
    }
    
    int iter[MAXN*MAXN];
    
    int DFS(int from,int to,int flow){
    	if(from == to || flow == 0)return flow;
    	for(int &i=iter[from] ; i<E[from].size() ; ++i){
    		Edge &e = E[from][i];
    		if(e.flow > 0 && deep[e.to] == deep[from]+1){
    			int nowflow = DFS(e.to,to,min(flow,e.flow));
    			if(nowflow > 0){
    				e.flow -= nowflow;
    				E[e.to][e.rev].flow += nowflow;
    				return nowflow;
    			}
    		}
    	}
    	return 0;
    }
    
    int Dinic(int from,int to){
    	int sumflow = 0;
    	while(BFS(from,to)){
    		memset(iter,0,sizeof iter);
    		int t;
    		while((t=DFS(from,to,INF)) > 0)sumflow += t;
    	}
    	return sumflow;
    }
    
    int main(){
    	
    	int T,M,N;
    	scanf("%d",&T);
    	while(T--){
    		init();
    		scanf("%d %d",&N,&M);
    		for(int i=0 ; i<N ; ++i)scanf("%s",&map[i]);
    		int num = 0;
    		for(int i=0 ; i<N ; ++i){
    			for(int j=0 ; j<M ; ++j){
    				if(map[i][j] == '*'){
    					++num;
    					Add(0,num,1);
    					while(j<M && map[i][j]!='#'){
    						if(map[i][j]!='o')boardx[i][j] = num;
    						++j;
    					}
    				}
    			}
    		}
    		for(int j=0 ; j<M ; ++j){
    			for(int i=0 ; i<N ; ++i){
    				if(map[i][j] == '*'){
    					++num;
    					Add(num,MAXN*MAXN-1,1);
    					while(i<N && map[i][j]!='#'){
    						if(map[i][j]!='o')boardy[i][j] = num;
    						++i;
    					}
    				}
    			}
    		}
    		for(int i=0 ; i<N ; ++i){
    			for(int j=0 ; j<M ; ++j){
    				if(boardx[i][j] && boardy[i][j])Add(boardx[i][j],boardy[i][j],1);
    			}
    		}
    		printf("%d
    ",Dinic(0,MAXN*MAXN-1));
    		for(int i=0 ; i<MAXN*MAXN ; ++i)E[i].clear();
    	}
    		
    	return 0;
    } 
  • 相关阅读:
    UWP中实现大爆炸效果(二)
    UWP中实现大爆炸效果(一)
    c# 【电影搜索引擎】采集电影站源码
    安利一个聚合搜索导航站,及怎么样设置成默认的搜索引擎
    女朋友经常问影视剧, 答不上来怎么办?
    宝塔linux面板, 服务器日志分析与流量统计这款插件的mysql版优化。
    苹果cms自动采集,重复执行遇到“上次执行时间: --跳过”的解决办法
    苹果cms, 后台设置保存不了的解决办法
    解决 C:WINDOWSsystem32inetsrv ewrite.dll 未能加载。返回的数据为错误.
    img error 图片加载失败的最佳方案
  • 原文地址:https://www.cnblogs.com/vocaloid01/p/9514064.html
Copyright © 2020-2023  润新知