題面傳送機
Sol
這題是否有解可以用並差集判斷 只不過太麻煩 本人沒寫
就直接用多次循環判斷了
老樣子 建立超源點S和超匯點E
1.從S向每一天的地球連有向邊 流量INF
2.從每一天的月亮向E連有向邊 流量INF
3.從上一天的每一個點向當天的對應點連有向邊 流量1INF
4.對於飛船,得到它上一天所在地,再獲取這一天所在地,在這兩個點之間連一條有向邊 流量爲載人量
判斷大小是否大於人數了 大於等於就推出循環 小於繼續
Code
#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstring>
#define inc(i) (i = -(~i))
#define dec(i) (i = ~(-i))
using namespace std;
const int N = 50 + 7 , M = N * N * 10 * 10 + 7 , INF = 1e9 + 7;
int n , m , k , Hp[M] , r[M] , s[N * 10][N * 10] , S , E , Ans , Sum;
int tot = 1 , Head[M] , Node[M] , Next[M] , W[M] , Dep[M];
int Father[M];
inline void Add(int u , int v , int w)
{
Next[inc(tot)] = Head[u] , Head[u] = tot , Node[tot] = v , W[tot] = w;
Next[inc(tot)] = Head[v] , Head[v] = tot , Node[tot] = u , W[tot] = 0;
}
struct Queue
{
int Que[M + 7] , l , r;
inline void cls() {l = 100 , r = 99;}
inline int top() {return Que[l];}
inline void push(int x) {Que[inc(r)] = x;}
inline bool full() {return r >= l;}
inline void pop() {inc(l);}
}Q;
inline bool BFS()
{
memset(Dep , 0 , sizeof(Dep));
Dep[S] = 1 , Q.cls() , Q.push(S);
int u , v;
while(Q.full())
{
u = Q.top() , Q.pop();
for(int i = Head[u] ; i ; i = Next[i])
{
v = Node[i];
if(!Dep[v] && W[i])
{
Dep[v] = Dep[u] + 1;
Q.push(v);
}
}
}
return Dep[E];
}
inline int DFS(int u , int lastc)
{
if(u == E || !lastc) return lastc;
int Flow , v , Now = 0;
for(int i = Head[u] ; i ; i = Next[i])
{
v = Node[i];
if(Dep[v] == Dep[u] + 1 && W[i])
{
Flow = DFS(v , min(lastc , W[i]));
if(Flow)
{
W[i] -= Flow;
W[i ^ 1] += Flow;
Now += Flow;
if(Now == lastc) break;
}
}
}
return Now;
}
inline int Max_Flow()
{
int Flow = 0;
while(BFS())
Flow += DFS(S , INF * 2);
return Flow;
}
int main()
{
scanf("%d%d%d" , &n , &m , &k);
n += 2;
S = M - 10 , E = S + 1;
for(int i = 1 ; i <= m ; inc(i))
{
scanf("%d%d" , Hp + i , r + i);
for(int j = 0 ; j < r[i] ; inc(j))
scanf("%d" , &s[i][j]) , s[i][j] += 2;
}
int Now_Day = 0;
while(Now_Day <= 567)
{
Add(Now_Day * n + 1 , E , INF);//Moon
Add(S , Now_Day * n + 2 , INF);//Sun
if(Now_Day)
{
for(int i = 1 ; i <= n ; inc(i))
Add((Now_Day - 1) * n + i , Now_Day * n + i , INF);
for(int i = 1 ; i <= m ; inc(i))
Add((Now_Day - 1) * n + s[i][(Now_Day - 1) % r[i]] , Now_Day * n + s[i][Now_Day % r[i]] , Hp[i]);
}
Sum += Max_Flow();
if(Sum >= k)
{
printf("%d" , Now_Day);
return 0;
}
inc(Now_Day);
}
putchar(48);
return 0;
}