1. 程式人生 > >bzoj1143: [CTSC2008]祭祀river(二分圖匹配)

bzoj1143: [CTSC2008]祭祀river(二分圖匹配)

題目傳送門
題面有點坑(對於我這種不讀題面的人來說)
題面上有個大大的圖。我看了一下好像是環誒。
我就以為這題有環。
一開始
我想:
既然有環,那麼我用強聯通縮點之後每個環最多隻能選出一個點咯。
然後我再在剩下的點裡面求點集,使兩兩不能互相到達。

然後我看錯了:
題目說顯然,水系中不會有環流(下圖描述一個環流的例子)
微笑。

然而這道題是裸的最大獨立集。
學(mo)了一發。
師兄blog
最大獨立集=點數-最大匹配。

程式碼實現:(有強聯通版本。。)

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream> #include<algorithm> using namespace std; struct node { int x,y,next; }a[1100];int len,last[110]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int belong[110],sta[1100],tp,cnt; int low[110],dfn[110],id; bool v[110]; void
dfs(int x) { low[x]=dfn[x]=++id; sta[++tp]=x;v[x]=true; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(dfn[y]==-1) { dfs(y); low[x]=min(low[x],low[y]); } else if(v[y]==true) low[x]=min(low[x],dfn[y]); } if
(dfn[x]==low[x]) { int i;cnt++; do { i=sta[tp--]; belong[i]=cnt; v[i]=false; }while(i!=x); } } int map[110][110],match[110]; bool chw[110]; bool get_match(int x) { for(int i=1;i<=cnt;i++) if(map[x][i]==true) if(chw[i]==false) { chw[i]=true; if(match[i]==0||get_match(match[i])==true) { match[i]=x;return true; } } return false; } int main() { int n,m;scanf("%d%d",&n,&m); len=0;memset(last,0,sizeof(last)); for(int i=1;i<=m;i++) { int x,y;scanf("%d%d",&x,&y); ins(x,y); } memset(dfn,-1,sizeof(dfn)); memset(sta,0,sizeof(sta)); memset(v,false,sizeof(v)); memset(low,0,sizeof(low)); tp=id=cnt=0; for(int i=1;i<=n;i++) if(dfn[i]==-1) dfs(i); memset(map,false,sizeof(map)); for(int i=1;i<=len;i++) if(belong[a[i].x]!=belong[a[i].y]) map[belong[a[i].x]][belong[a[i].y]]=true; for(int k=1;k<=cnt;k++) for(int i=1;i<=cnt;i++) for(int j=1;j<=cnt;j++) if(map[i][k]==true&&map[k][j]==true) map[i][j]=true; //要加floyd使得間接連通也算聯通 int ans=0;memset(match,0,sizeof(match)); for(int i=1;i<=cnt;i++) { memset(chw,false,sizeof(chw)); if(get_match(i)==true) ans++; } printf("%d\n",cnt-ans); return 0; }

不加強聯通:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
int map[110][110],match[110];
bool chw[110];int n;
bool get_match(int x) {
    for(int i=1;i<=n;i++)
        if(map[x][i]==true)
            if(chw[i]==false) {
                chw[i]=true;
                if(match[i]==0||get_match(match[i])==true) {
                    match[i]=x;return true;
                }
            }
    return false;
}
int main() {
    int m;scanf("%d%d",&n,&m);
    memset(map,false,sizeof(map));
    for(int i=1;i<=m;i++) {
        int x,y;scanf("%d%d",&x,&y);
        map[x][y]=true;
    }
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(map[i][k]==true&&map[k][j]==true)
                    map[i][j]=true;
    int ans=0;
    memset(match,0,sizeof(match));
    for(int i=1;i<=n;i++) {
        memset(chw,false,sizeof(chw));
        if(get_match(i)==true)
            ans++;
    }
    printf("%d\n",n-ans);
    return 0;
}

相關推薦

bzoj1143: [CTSC2008]祭祀river二分匹配

題目傳送門 題面有點坑(對於我這種不讀題面的人來說) 題面上有個大大的圖。我看了一下好像是環誒。 我就以為這題有環。 一開始 我想: 既然有環,那麼我用強聯通縮點之後每個環最多隻能選出一個點咯。 然後我再在剩下的點裡面求點集,使兩兩不能互相到達。

uva 12083 Guardian of Decency 二分匹配

eas eof aid spa ams oba school eache lib uva 12083 Guardian of Decency Description Frank N. Stein is a very conservative high

【題解】 [ZJOI2007]矩陣遊戲 二分匹配

void 輸出 oid img bre pro href zjoi2007 sca 原題目戳我 Solution: 方法很巧妙,我們把每個裝備的屬性 與 裝備編號連起來 從1-10000跑二分圖,如果出現斷層,就退出,輸出答案就好。 memset清理bool快一點,int洛

【題解】 [ZJOI2009]假期的宿舍 二分匹配

src max span true bool box 同學 down DC Solution: 處理出床位、要留校的人(註意來訪問的人一定住校),和人與人的關系(連邊) 再接著就是二分圖。 註意的就是連向的人必須是有床位的 還要註意的就是只用判斷住校的同學 二分圖板子都

【題解】 [NOI2009]變換序列 二分匹配

down its -i AD out emp 二分圖 post while 懶得復制,戳我戳我 Solution: 這個題面出的很毒瘤,讀懂了其實是個板子題qwq 題面意思:有個\(0\)至\(N-1\)的數列是由另一個數列通過加減得到的,相當於將\(A_i\)變成\(i

BZOJ1854:遊戲二分匹配

find als 數值 每次 輸入 algo names sin str lxhgww最近迷上了一款遊戲,在遊戲裏,他擁有很多的裝備,每種裝備都有2個屬性,這些屬性的值用[1,10000]之間的數表示。當他使用某種裝備時,他只能使用該裝備的某一個屬性。並且每種裝備最多只能使

洛谷P2756 飛行員配對方案問題二分匹配

好用 string dep 二分圖匹配 匈牙利 ini ron clu fread 傳送門 一個基礎的二分圖匹配(雖然今天才學會) 因為不會匈牙利算法只好用網絡流做 先新建一個超級源和超級匯,源往所有左邊的點連邊,所有右邊的點往匯連邊 然後跑一邊最大流就好了

HDU1083 :Courses二分匹配

ostream 鏈接 ise ide sat mit ask first repr Cources Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To

Prime Set ZOJ - 3988 二分匹配

Given an array of  integers , we say a set  is a prime set of the given array, if  and  is prime. BaoBa

BZOJ1191:超級英雄二分匹配

[HNOI2006]超級英雄Hero 題目連結:https://www.lydsy.com/JudgeOnline/problem.php?id=1191 Description: 現在電視臺有一種節目叫做超級英雄,大概的流程就是每位選手到臺上回答主持人的幾個問題,然後根據回答問題的 多少獲

BZOJ 1191: [HNOI2006]超級英雄Hero二分匹配

1191: [HNOI2006]超級英雄Hero Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6263  Solved: 2799[Submit][Status][Di

演算法模板:匈牙利演算法模板二分匹配

 pascal匈牙利演算法模板 //匈牙利演算法模板 var i,j,n,m,so,x,y,ans,t:longint; h:array[1..200]of longint; p:array[1..400]of longint; bz,gcl:array[0..40

2017 CCPC秦皇島 H Prime Set二分匹配

是一個二分圖匹配 而我和舟神bbbbbbbbbbbbbbbbb了大概一個小時,不想寫二分圖,甚至想建網路流模型 我也是服了,可能這就是不會算時間複雜度的菜雞吧 題目思路: 1.打素數表 2.將奇數和偶數分開到兩邊,因為只有奇數加偶數才可以是素數。 3.1特殊處理,

2018.10.23【SCOI2015】【洛谷P4251】【BZOJ4443】小凸玩矩陣二分答案二分匹配

洛谷傳送門 解析: 並不知道這道題為什麼在洛谷上是紫題,感覺好水啊。 思路: 把行和列分別當做兩部分圖,中間連邊,可以發現這是一個二分圖匹配。 既然要求kkk大值最小,顯然想到二分。那就是第n−k+1

BZOJ 1059二分匹配

題面 傳送門 分析 遊戲的操作有以下性質: 1.如果兩個格子在同一列,那麼無論如何操作,這兩個格子都在同一列。 2.如果兩個格子在同一行,那麼無論如何操作,這兩個格子都在同一行。 3.可以通過操作改變改點在對應行和列中的位置。 我們發現對於第i行,我們必須要找到某一列上的黑格子挪過來放在對角線上

Uva 10615 Rooks二分匹配

題意:給一個n * n的棋盤,有若干個車,現在要給車塗色使得同一行或者同一列的任意兩個車顏色不同,問至少需要多少種顏色,並給出其中一種塗色方式。 思路:每一行和每一列的車的個數的最大值就是需要多少種顏色。分兩個集合,行集合和列集合,然後在有車的位置(i, j)讓i屬於行集

HDU-1533 Going Home二分匹配

最近開始做最小費用流的題目,該題是二分圖完美匹配下的最小權匹配,所謂完美匹配就是說從源點流入的總流量等於從匯點流出的總流量,在這種狀態下的最小費用 。  那麼顯然是要套用最小費用流模板,另外二分圖匹配的第一步就是要劃分集合,劃分兩個集合,集合A與源點相連,集合B與匯點相連,

2063 過山車二分匹配

題目連結: 題解: 二分圖匹配模板題。 AC程式碼: #include <iostream> #include <algorithm> #include

匈牙利演算法二分匹配

好,來講簡單的東西了 匈牙利演算法 也就是二分圖匹配 Q二分圖匹配是什麼? 還是先看題比較好 公牛和母牛 【問題描述】 有n只公牛和m只母牛,然後每隻公牛都能和幾隻的母牛配對。在每隻公牛隻能配對一隻母牛的情況下,求能為牛們配對最多多少對?

bzoj1143 CTSC2008祭祀river最大獨立集--二分匹配

題目: 我是超連結 題解: 尋找一個最大點集A,滿足∀u,v∈V,(u,v)∉E  二分圖的最大獨立集=頂點數-最大匹配  程式碼: #include <cstdio> #include