hdu3551 Hard Problem 【一般圖匹配】
題意:給定一個無向圖,(可能重邊)問能否通過刪邊,得到每個點的度數(d)為給定的度數(D)。
分析:我們先不管邊上的兩點是哪個,只考慮這兩點的度數,現在刪掉某條邊,這邊上的兩點的度數都不為零那麼就可以刪,
這樣我們可以把這兩個“度”匹配,如果所有的匹配可,那麼所有多餘的都可以刪掉了。我們這樣將所有的點拆成它度數個點,
這樣我們就可以用帶花樹開花取求。建邊的時候不需要把兩邊上的所有點建邊,這樣會有很多邊重複,我們可以建立一箇中間邊,
使得這兩坨點間接相鄰。
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<queue> #include<cmath> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f #define Mn 810 #define Mm 200005 #define mod 1000000007 #define CLR(a,b) memset((a),(b),sizeof((a))) #define CPY(a,b) memcpy ((a), (b), sizeof((a))) #pragma comment(linker, "/STACK:102400000,102400000") #define ul u<<1 #define ur (u<<1)|1 using namespace std; typedef long long ll; struct edge { int v,next; }e[Mm]; int tot,head[Mn]; void addedge(int u,int v) { e[tot].v=v; e[tot].next=head[u]; head[u]=tot++; } int cnt,pre[Mn]; int findpre(int x) { return x==pre[x]?pre[x]:pre[x]=findpre(pre[pre[x]]); } void ol(int a,int b) { a=findpre(a); b=findpre(b); if(a!=b) pre[a]=b; } int lk[Mn],vis[Mn],mark[Mn],match[Mn],ne[Mn]; int lca(int x,int y) { static int t=0;t++; while(1) { if(x!=-1) { x=findpre(x); if(vis[x]==t) return x; vis[x]=t; if(match[x]!=-1) x=ne[match[x]]; else x=-1; } swap(x,y); } } queue<int> q; void group(int a,int p) { while(a!=p) { int b=match[a],c=ne[b]; if(findpre(c)!=p) ne[c]=b; if(mark[b]==2) mark[b]=1,q.push(b); if(mark[c]==2) mark[c]=1,q.push(c); ol(a,b),ol(b,c); a=c; } } void aug(int s) { for(int i=0;i<=cnt;i++) { ne[i]=-1; pre[i]=i; mark[i]=0; vis[i]=-1; } mark[s]=1; while(!q.empty()) q.pop(); q.push(s); while((!q.empty())&&match[s]==-1) { int u=q.front(); q.pop(); for(int i=head[u];~i;i=e[i].next) { int v=e[i].v; if(match[u]==v||findpre(u)==findpre(v)||mark[v]==2) continue; if(mark[v]==1) { int r=lca(u,v); if(findpre(u)!=r) ne[u]=v; if(findpre(v)!=r) ne[v]=u; group(u,r); group(v,r); } else if(match[v]==-1) { ne[v]=u; for(int x=v;~x;) { int y=ne[x]; int mv=match[y]; match[x]=y,match[y]=x; x=mv; } break; } else { ne[v]=u; q.push(match[v]); mark[match[v]]=1; mark[v]=2; } } } } int degree[Mn]; int d[Mn]; int U[Mn],V[Mn]; int id[Mn],num[Mn]; void init() { tot=0;cnt=1; CLR(head,-1); CLR(id,0); CLR(degree,0); } void build(int n,int m) { for(int i=1;i<=m;i++) { int u=U[i],v=V[i]; if(!id[u]) { id[u]=cnt; num[u]=cnt+d[u]-1; cnt+=d[u]; } if(!id[v]) { id[v]=cnt; num[v]=cnt+d[v]-1; cnt+=d[v]; } if(!id[n+i+1]) { id[n+i+1]=cnt; num[n+i+1]=cnt+1; cnt+=2; } int t=id[n+i+1]; addedge(t,t+1); addedge(t+1,t); for(int j=id[u];j<=num[u];j++) addedge(t,j),addedge(j,t); for(int j=id[v];j<=num[v];j++) addedge(t+1,j),addedge(j,t+1); } } int main() { int t; scanf("%d",&t); for(int cas=1;cas<=t;cas++) { int n,m;init(); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d",&U[i],&V[i]); degree[U[i]]++; degree[V[i]]++; } int flag=1; for(int i=1;i<=n;i++) { scanf("%d",&d[i]); if(degree[i]<d[i]) flag=0; else d[i]=degree[i]-d[i]; } printf("Case %d: ",cas); if(!flag) { printf("NO\n"); continue; } build(n,m); int ans=0; cnt--; //cout<<cnt<<endl; for(int i=1;i<=cnt;i++) { match[i]=-1; } for(int i=1;i<=cnt;i++) { if(match[i]==-1) aug(i); } for(int i=1;i<=cnt;i++) { if(match[i]!=-1) ans++; } if(ans==cnt) { printf("YES\n"); } else { printf("NO\n"); } } return 0; }
相關推薦
hdu3551 Hard Problem 【一般圖匹配】
題意:給定一個無向圖,(可能重邊)問能否通過刪邊,得到每個點的度數(d)為給定的度數(D)。 分析:我們先不管邊上的兩點是哪個,只考慮這兩點的度數,現在刪掉某條邊,這邊上的兩點的度數都不為零那麼就可以刪, 這樣我們可以把這兩個“度”匹配,如果所有的匹配可,那麼所有多餘的都
【最短路】【二分圖匹配】【樹形背包DP】Day 10.8
void second eof 最小 span har mes find names T1 最短路 1 #include <cstdio> 2 #include <queue> 3 #include <iostream>
hdu 1045 Fire Net 【二分圖匹配】
進行 col numbers res clu 意思 archive 多少 color <題目鏈接> <轉載於 >>> > 題目大意: 這題意思是給出一張圖,圖中‘X‘表示wall,‘.‘表示空地,可以放置炮臺,同一條直線上只
HDU 3829 Cat VS Dog (最大獨立集)【二分圖匹配】
<題目連結> 題目大意: 動物園有n條狗。m頭貓。p個小孩,每一個小孩有一個喜歡的動物和討厭的動物。如今動物園要轉移一些動物。假設一個小孩喜歡的動物在,不喜歡的動物不在,他就會happy。問動物最多能使幾個小孩happy。 解題分析: 因為本題不同的小孩之間喜好可能會產生衝突,所以,要使最
【二分圖匹配】HDU
題意: 給出一張圖,‘X’代表牆,‘.’ 代表空地。在空地上放一些炮塔,炮塔不能處在同一行同一列,除非被牆隔開。問最多能放多少個炮塔。 題解: 這題其實可以二進位制暴力模擬去做,但也可以用二分
過山車 【二分圖匹配】
## **題目描述**: RPG girls今天和大家一起去遊樂場玩,終於可以坐上夢寐以求的過山車了。可是,過山車的每一排只有兩個座位,而且還有條不成文的規矩,就是每個女生必須找個個男生做partn
【二分圖匹配】 最小點覆蓋==最大匹配數
先說一下,什麼叫做最小覆蓋點。 在一個二分圖中,一個x部或y部的覆蓋點可以覆蓋與之相連的所有線段,選擇一些點,使得覆蓋所有線段,點數最少。 König定理:最小覆蓋點數==最大匹配數 我有兩個證明。 **********************
LOJ2276 [HAOI2017] 新型城市化 【二分圖匹配】【tarjan】
分析 stack add 節點 題目 style bits 連通 發現 題目分析: 這題出的好! 首先問題肯定是二分圖的最大獨立集,如果刪去某條匹配邊之後獨立集是否會變大。 跑出最大流之後流滿的邊就是匹配邊。 如果一個匹配邊的兩個端點在一個強連通分量裏,那這條邊刪掉
【二分圖匹配入門專題1】E - Air Raid hdu1151【最小路徑覆蓋】
eno rate ask return red size all file 痛苦 Consider a town where all the streets are one-way and each street leads from one intersection to
【二分圖匹配入門專題1】F - COURSES poj1469【最大匹配--匈牙利算法模板題】
nbsp possible count dfs positive owin not hat first Consider a group of N students and P courses. Each student visits zero, one or more t
【二分圖匹配入門專題1】D - Matrix hdu2119【最小頂點覆蓋】
sample ins ever != sca either dfs ret int Give you a matrix(only contains 0 or 1),every time you can select a row or a column and delete
【二分圖匹配入門專題1】M - Cyclic Tour hdu1853【km算法--判斷自重邊】
初始化 case test case 思路 contain first rst ant eve There are N cities in our country, and M one-way roads connecting them. Now Little Tom wa
BZOJ2437 [Noi2011]兔兔與蛋蛋 【博弈論 + 二分圖匹配】
read cls www 判斷 ring get 必須 out AI 題目鏈接 BZOJ2437 題解 和JSOI2014很像 只不過這題動態刪點 如果我們把空位置看做\(X\)的話,就會發現我們走的路徑是一個\(OX\)交錯的路徑 然後將圖二分染色,當前點必勝,當且僅當當
【二分圖匹配/匈牙利演算法】飛行員配對方案問題
P2756 飛行員配對方案問題 確認過眼神, 是二分圖匹配板子題啦!!! 跑個匈牙利, 有匹配的輸出, 記得先輸出外籍飛行員, 因為有spj順序無所謂啦qwq 最近A的最順利的題了哈哈哈哈哈哈開心!!!!!!!! 1 #include<cstdio> 2 #incl
HDU 1045 Fire Net 【連通塊的壓縮 二分圖匹配】
題目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav
2018 BJTU Summer Training 【二分圖匹配 & 網路流 & 費用流】
前言(瞎BB) 網路流是我在OI生涯學的最後一個演算法,它很適合演算法競賽,因為它需要建立模型(圖)來反映題目中的限制條件,而且可以得出一些最優的東西(最大流),或者是搞出方案(搜尋殘量網路),這些都是演算法競賽最喜歡的。 高中就聽說過一位神犇,憑藉一手網路流解決了許多標
【BZOJ 1854】【SCOI 2010】遊戲【並查集 & 二分圖匹配】
Description lxhgww最近迷上了一款遊戲,在遊戲裡,他擁有很多的裝備,每種裝備都有2個屬性,這些屬性的值用[1,10000]之間的數表示。當他使用某種裝備時,他只能使用該裝備的某一個屬性。並且每種裝備最多隻能使用一次。 遊戲進行到最後,lxhgw
CodeForces 776D The Door Problem【並查集】
merge cnblogs 表示 turn pro name 所有 force mes CodeForces 776D The Door Problem【並查集】並查集 設 f 1--m 表示 開的情況 m+1--2*m 表示關的情況 對於每盞燈 如果他 是關
正則表達式【範圍性匹配】
bsp com pre www. find compile 轉義 什麽 sna 1、 import re key = r"<html><body><h1>hello world<h1></body></ht
【計算幾何】【二分圖判定】Gym - 101485C - Cleaning Pipes
你是 i+1 ace 機器 ble mes 方案 clu str 題意:有n個水井,每個水井發出一些管線(都是線段),然後每條管線上最多只有一個水井。所有從不同的水井發出的管線的相交點都是清潔點(不存在清潔點是大於兩條管線點的交點)。你需要在某些管線上放出一些機器人,它們會