[網絡流24題13] 星際轉移問題

題面傳送機

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章