洛谷 P2754 [CTSC1999] 家园 / 星际转移问题——题解

#ifdef ONLINE_JUDGE 
#else 
#define Qiu_Cheng 
#endif 
#include <bits/stdc++.h> 
#define int long long 
using namespace std; 
// typedef long long ll; 
const int N=2e6+5,mod=1e9+7,inf=INT_MAX; 
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118; 
// const int M=mod1*mod2;
inline int read()
{
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
    return x*f;
}
inline void write(int x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
int n,m,fa[N];
int pos[N],dep[N];
struct node{int to,c,lp;};
vector<node>g[N];
int findx(int x)
{
    if(fa[x]==x)return x;
    return fa[x]=findx(fa[x]);
}
void git(int x,int y)
{
    int a=findx(x),b=findx(y);
    if(a!=b) fa[a]=b;
}
void add(int from,int to,int c)
{
    g[from].push_back((node){to,c,(int)g[to].size()});
    g[to].push_back((node){from,0,(int)g[from].size()-1});
}
void fc(int s)
{
    memset(dep,-1,sizeof(dep));
    dep[s]=0;
    queue<int>q;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(auto v:g[u])
        {
            if(v.c>0&&dep[v.to]<0)
            {
                dep[v.to]=dep[u]+1;
                q.push(v.to);
            }
        }
    }
}
int dfs(int u,int t,int f)
{
    if(u==t||!f) return f;
    int ans=0;
    for(int &i=pos[u];i<g[u].size();i++)
    {
        auto &x=g[u][i];
        if(x.c>0&&dep[x.to]==dep[u]+1)
        {
            int frz=dfs(x.to,t,min(f,x.c));
            if(frz>0)
            {
                x.c-=frz;g[x.to][x.lp].c+=frz;
                f-=frz;ans+=frz;
                if(!f)break;
            }
        }
    }
    return ans;
}
int max_flow=0;
int dinic(int s,int t)
{
    int flow=0;
    while(1)
    {
        fc(s);
        if(dep[t]==-1) return flow;
        memset(pos,0,sizeof(pos));
        flow+=dfs(s,t,inf);
    }
}
int k,p[N],num[505],zhan[505][505];
int gett(int x,int y){return (x-1)*(n+2)+y;}
inline void solve()
{
    int S=0,T=114514;cin>>n>>m>>k;
    for(int i=1;i<=n+2;i++) fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        cin>>p[i]>>num[i];
        for(int j=1;j<=num[i];j++)
        {
            cin>>zhan[i][j];
            if(zhan[i][j]==0) zhan[i][j]=n+1;//地球n+1
            if(zhan[i][j]==-1) zhan[i][j]=n+2;//月球是n+2
            if(j!=1) git(zhan[i][j-1],zhan[i][j]);//加入并查集
        }
    }
    // cout<<findx(n+1)<<" "<<findx(n+2)<<endl;
    if(findx(n+1)!=findx(n+2)){cout<<0<<endl;return;}
    int ans=2;
    add(S,n+1,k);
    add(n+2,T,inf);
    while(1)
    {
        add(gett(ans,n+2),T,inf);//连day()月球到
        for(int i=1;i<=n+2;i++) add(gett(ans-1,i),gett(ans,i),inf);
        for(int i=1;i<=m;i++)
        {
            int a=gett(ans-1,zhan[i][(ans-2)%num[i]+1]);//前一天的位置
            int b=gett(ans,zhan[i][(ans-1)%num[i]+1]);
            add(a,b,p[i]);
        }
        max_flow+=dinic(S,T);;
        if(max_flow>=k)
        {
            cout<<ans-1;
            return;
        }
        ans++;
    }
}
signed main() 
{ 
#ifdef Qiu_Cheng 
    freopen("1.in","r",stdin); 
    freopen("1.out","w",stdout); 
#endif 
    // ios::sync_with_stdio(false); 
    // cin.tie(0); cout.tie(0); 
    // int QwQ; 
    // cin>>QwQ; 
    // while(QwQ--)solve(); 
    solve(); 
    return 0; 
}
//12 825076913 0 173167432
//  6666   66666  666666 
// 6    6  6   6      6 
// 6    6  6666      6 
// 6    6  6  6    6 
//  6666   6   6  6666666

//g++ -O2 -std=c++14 -Wall "-Wl,--stack= 536870912 " cao.cpp -o cao.exe
posted @ 2025-01-08 19:10  Nightmares_oi  阅读(1)  评论(0编辑  收藏  举报