bzoj4205 卡牌配對

2021-08-08 12:37:04 字數 1835 閱讀 8259

卡牌配對

題目背景:

bzoj4205

分析:我相信很多人第一反應都是暴力連邊然後暴力二分圖匹配,然後我的常數還沒有小到n2過

30000

,所以我們來想想該怎麼辦,考慮到

200以內的質數只有

46個,我們可以選擇增加

3 * 46 * 46

個點,將左邊的某種屬性有第

i個質因數,另乙個屬性有第

j個質因數的點連向對應的乙個點,並將這個點與右邊滿足上述條件的點相連,然後新建源點匯點就可以跑最大流了,大概是乙個

70000

個點,2000000

條邊的網路流(

200以內的數最多

3個質因數,所以最多不超過

27條邊),他竟然讓大膽玩高漸進複雜度,那當然就直接上吧。

source:

/*

created by scarlyw

*/#include #include #include #include #include #include #include #include #include #include inline char read()

return *s++;}

///*

templateinline void r(t &x)

for (x = 0; isdigit(c); c = read())

x = ((x << 2) + x << 1) + (c ^ '0');

if (iosig) x = -x;

}//*/

const int out_len = 1024 * 1024;

char obuf[out_len], *oh = obuf;

inline void write_char(char c)

templateinline void w(t x) }

inline void flush()

/*templateinline void r(t &x)

//*/

const int maxn = 70000 + 10;

const int maxx = 200 + 5;

const int prime[50] = ;

struct node

} ;

struct data x[maxn], y[maxn];

std::vectoredge[maxn];

int n1, n2, n, s, t;

int id[3][maxx][maxx], dis[maxn], gap[maxn];

inline void add_edge(int x, int y, int w)

inline void read_in()

inline int solve(int n, int *a)

if (n != 1) a[++top] = n;

return top;}

inline void build_graph()

for (int i = 1; i <= n2; ++i) }

///*

inline int sap(int cur, int flow, int s, int t, int n)

}if (--gap[dis[cur]] == 0) dis[s] = n;

return gap[++dis[cur]]++, temp[cur] = 0, del;}

inline int sap(int s, int t, int n)

//*/

int main()

BZOJ4205 卡牌配對

對於兩張卡牌,如果存在兩種屬性值不互質,則可以匹配。只考慮200以內的質數,一共有46個,可以新建3 46 46個點來表示一類屬性值中有這兩種質數的卡牌。然後對於每張卡牌,列舉它的質因子,最多只有3個,如此建圖求出最大流即可。includeconst int n 66500,inf 0u 2,p 2...

BZOJ4205 卡牌配對

現在有一種卡牌遊戲,每張卡牌上有三個屬性值 a,b,c。把卡牌分為x,y兩類,分別有n1,n2張。兩張卡牌能夠配對,當且僅當,存在至多一項屬性值使得兩張卡牌該項屬性值互質,且兩張卡牌類別不同。比如一張x類卡牌屬性值分別是225,233,101,一張y類卡牌屬性值分別為115,466,99。那麼這兩張...

BZOJ4205 卡牌配對(網路流)

現在有一種卡牌遊戲,每張卡牌上有三個屬性值 a,b,c。把卡牌分為x,y兩類,分別有n1,n2張。兩張卡牌能夠配對,當且僅當,存在至多一項屬性值使得兩張卡牌該項屬性值互質,且兩張卡牌類別不同。比如一張x類卡牌屬性值分別是225,233,101,一張y類卡牌屬性值分別為115,466,99。那麼這兩張...