↓ 跳过正文
  1. Posts/

hdu 5285 wyh2000 and pupil (交叉染色法,二分图点集差最大)

·869 字·2 分钟

题目链接:hdu 5285 题目lianjie

题意:给定n个小朋友,以及小朋友之间的关系,要求将小朋友分成两组,**并且每组至少一个人,**现在问能否这样分组,如果有解,输出两组的人数,并保证第一组的人数尽可能地大。

思路:。。。一开始看到n的数据范围。。。想当然的以为会给认识的人的关系。。。尼玛。。。求个补图就够受的了。。。。不会做,卒。

结果发现。。竟然给的是两个人不认识的关系。。。2333

那么我们来交叉染色。。。

实际上交叉染色的过程中,颜色相同的点属于二分图中相同的点集合。

交叉染色其实是在模拟交错轨的过程…?

由于图不一定联通,可能由多个联通块。

我们在交叉染色的时候记录一下0,1的个数(也就是两个点集的大小)

然后每次把大的累加(因为没说不认识的就是默认认识了。。。)

无解的情况有:任何一个联通快无解或者n<=1

此外还需要注意,m可能为0.

特判一下,m为0或者为1,直接输出n-1和1.

以及!

n<=1的无解是在特判m之前的。。。。我好傻啊。

n<=1的无解是在特判m之前的。。。。我好傻啊。

n<=1的无解是在特判m之前的。。。。我好傻啊。

代码实现
  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年09月02日 星期五 14时41分35秒
  4File Name :code/hdu/5285.cpp
  5************************************************ */
  6#include <cstdio>
  7#include <cstring>
  8#include <iostream>
  9#include <algorithm>
 10#include <vector>
 11#include <queue>
 12#include <set>
 13#include <map>
 14#include <string>
 15#include <cmath>
 16#include <cstdlib>
 17#include <ctime>
 18#define fst first
 19#define sec second
 20#define lson l,m,rt<<1
 21#define rson m+1,r,rt<<1|1
 22#define ms(a,x) memset(a,x,sizeof(a))
 23typedef long long LL;
 24#define pi pair < int ,int >
 25#define MP make_pair
 26using namespace std;
 27const double eps = 1E-8;
 28const int dx4[4]={1,0,0,-1};
 29const int dy4[4]={0,-1,1,0};
 30const int inf = 0x3f3f3f3f;
 31const int M = 2E5+7;
 32const int N = 1E5+7;
 33int n,m;
 34int head[N];
 35int col[N];
 36struct Edge
 37{
 38    int v;
 39    int nxt;
 40}edge[M];
 41int cnt;
 42int cnt0,cnt1;
 43void addedge(int u ,int v)
 44{
 45    edge[cnt].v = v;
 46    edge[cnt].nxt = head[u];
 47    head[u] = cnt;
 48    cnt++;
 49}
 50int dfs( int u,int x,int fa)
 51{
 52    col[u] = x;
 53    if (x==0) cnt0++;else cnt1++;
 54    for ( int i = head[u] ; i !=-1 ; i = edge[i].nxt)
 55    {
 56	int v = edge[i].v;
 57	if (v==fa) continue;
 58	if (col[v]==1-x) continue;
 59	if (col[v]==x) return -1;
 60	if (!dfs(v,1-x,u)) return -1;
 61    }
 62    return max(cnt0,cnt1);
 63}
 64int  solve()
 65{
 66    int res = 0  ;
 67    for ( int i = 1 ; i <= n ; i++)
 68    {
 69	if (col[i]!=-1) continue;
 70	cnt0 = cnt1 = 0 ;
 71	int tmp = dfs(i,0,-1);
 72	if (tmp==-1) return -1;
 73	res+=tmp;
 74    }
 75    return res;
 76}
 77int main()
 78{
 79	#ifndef  ONLINE_JUDGE
 80	freopen("code/in.txt","r",stdin);
 81  #endif
 82	int T;
 83	cin>>T;
 84	while (T--)
 85	{
 86	    scanf("%d%d",&n,&m);
 87	    cnt = 0 ;
 88	    ms(head,-1);
 89	    ms(col,-1);
 90	    for ( int i = 1 ; i <= m ; i++)
 91	    {
 92		int u,v;
 93		scanf("%d%d",&u,&v);
 94		addedge(u,v);
 95		addedge(v,u);
 96	    }
 97	    if (n<2)
 98	    {
 99		puts("Poor wyh");
100		continue;
101	    }
102	    if (m<=1)
103	    {
104		printf("%d %d\n",n-1,1);
105		continue;
106	    }
107	    int ans = solve();
108	    if (ans==-1) puts("Poor wyh");
109	    else printf("%d %d\n",ans,n-ans);
110	}
111  #ifndef ONLINE_JUDGE
112  fclose(stdin);
113  #endif
114    return 0;
115}

相关文章

hdu 4751 Divide Groups (反向建图,判断二分图,交叉染色法)

·583 字·2 分钟
hdu 4751 题目链接 题意:n个人,给出每个人认识的人的信息。问能否将这些人分成两组,保证每组至少1个人,并且两两互相认识。 思路:首先是反向建图。由于要求同组内两个人互相认识,那么两个人u,v,只要u不认识v或者v不认识有一个满足,就连接双向边u,v,表示u,v不能分到同一组。

hdu 5215 Cycle(交叉染色法判断无向图的奇偶环)

·1014 字·3 分钟
hdu 5215 思路:询问一个无向图,是否存在奇数环,以及是否存在偶数环。(不同的环之间可以有相同的点,不能有相同的边) 思路:一开始的想法是,根据染色的奇偶性,如果染色到某个之前染色过的点,和当前要染的颜色相同,说明存在奇数环,不同,说明存在偶数环。

hdu 2444 The Accomodation of Students (交叉染色法+匈牙利算法)

·460 字·1 分钟
hdu 2444题目链接 题意:判断一个有向图是否是二分图,是的话求最大匹配数。 思路:交叉染色判二分图,是的话跑遍匈牙利即可。1A. 代码实现 1/* *********************************************** 2Author :111qqz 3Created Time :2016年09月01日 星期四 14时24分36秒 4File Name :code/hdu/2444.cpp 5************************************************ */ 6#include <cstdio> 7#include <cstring> 8#include <iostream> 9#include <algorithm> 10#include <vector> 11#include <queue> 12#include <set> 13#include <map> 14#include <string> 15#include <cmath> 16#include <cstdlib> 17#include <ctime> 18#define fst first 19#define sec second 20#define lson l,m,rt<<1 21#define rson m+1,r,rt<<1|1 22#define ms(a,x) memset(a,x,sizeof(a)) 23typedef long long LL; 24#define pi pair < int ,int > 25#define MP make_pair 26using namespace std; 27const double eps = 1E-8; 28const int dx4[4]={1,0,0,-1}; 29const int dy4[4]={0,-1,1,0}; 30const int inf = 0x3f3f3f3f; 31const int N=205; 32int n,m; 33vector<int>edge[N]; 34int col[N]; 35int link[N]; 36bool vis[N]; 37void init() 38{ 39 for ( int i = 0 ; i <= n ; i++) edge[i].clear(); 40 ms(col,-1); 41} 42bool dfs( int u,int x) 43{ 44 col[u] = x; 45 int siz = edge[u].size(); 46 for ( int i = 0 ; i < siz; i++) 47 { 48 int v = edge[u][i]; 49 if (col[v]==1-x) continue; 50 if (col[v]==x) return false; 51 if (!dfs(v,1-x)) return false; 52 } 53 return true; 54} 55bool solve() 56{ 57 for ( int i = 1 ; i <= n ; i++) if (col[i]==-1) if (!dfs(i,0)) return false; 58 return true; 59} 60bool Find( int u) 61{ 62 int siz = edge[u].size(); 63 for ( int i = 0 ; i < siz; i ++) 64 { 65 int v = edge[u][i]; 66 if (vis[v]) continue; 67 vis[v] = true; 68 if (link[v]==-1||Find(link[v])) 69 { 70 link[v] = u; 71 return true; 72 } 73 } 74 return false; 75} 76int hung( int n) 77{ 78 int ans = 0 ; 79 ms(link,-1); 80 for ( int i = 1 ; i <= n ; i++) 81 { 82 ms(vis,false); 83 if (Find(i)) ans++; 84 } 85 return ans; 86} 87int main() 88{ 89 #ifndef ONLINE_JUDGE 90 freopen("code/in.txt","r",stdin); 91 #endif 92 while (~scanf("%d %d",&n,&m)) 93 { 94 init(); 95 for ( int i = 1 ; i <= m ; i++) 96 { 97 int u,v; 98 scanf("%d%d",&u,&v); 99 edge[u].push_back(v); 100 } 101 if (!solve()) 102 { 103 puts("No"); 104 } 105 else 106 { 107 int ans = hung(n); 108 printf("%d\n",ans); 109 } 110 } 111 #ifndef ONLINE_JUDGE 112 fclose(stdin); 113 #endif 114 return 0; 115}

BZOJ 3680: 吊打XXX (广义费马点,模拟退火+爬山)

3680: 吊打XXX # Time Limit: 10 Sec Memory Limit: 128 MBSec Special Judge Submit: 2043 Solved: 732 [Submit][Status][Discuss] Description # gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty。gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了。蒟蒻们将 n个gty吊在n根绳子上,每根绳子穿过天台的一个洞。这n根绳子有一个公共的绳结x。吊好gty后蒟蒻们发现由于每个gty重力不同,绳 结x在移动。蒟蒻wangxz脑洞大开的决定计算出x最后停留处的坐标,由于他太弱了决定向你求助。 不计摩擦,不计能量损失,由于gty足够矮所以不会掉到地上。