哈爾濱理工大學第十屆程序設計競賽-養花——(網絡流+最大流)

總結

當時比賽沒寫到這裏來,後面聽說網絡流,就試着嘗試一下,發現還是比較容易建模,然後就是裸題了。

問題

代碼量大了,還是多寫一個變量,自己很粗心,總是容易寫錯i寫成a1a2,弄得我錯了好幾次

鏈式前向星,自己0起點,那就得-1結束,1起點那就得0結束,每次用得時候總是忘了,head忘記清空爲-1了,難搞哦

題目鏈接

//#pragma GCC optimize(2)
//#pragma GCC target ("sse4")
#include<bits/stdc++.h>
//typedef long long ll;
#define ull       unsigned long long
#define int       long long
#define F           first
#define S           second
#define endl        "\n"//<<flush
#define eps         1e-6
#define base        131
#define lowbit(x)   (x&(-x))
#define PI          acos(-1.0)
#define inf         0x3f3f3f3f
#define MAXN        0x7fffffff
#define INF         0x3f3f3f3f3f3f3f3f
#define ferma(a,b)  pow(a,b-2)
#define mod(x)      (x%mod+mod)%mod
#define pb          push_back
#define decimal(x)  cout << fixed << setprecision(x);
#define all(x)      x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS         ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
void file()
{
#ifdef ONLINE_JUDGE
#else
    freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin);
    //  freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
#endif
}
const int N=2e5+5;
struct node
{
    int next,to,dis;
} edge[N];
int head[N],pos=-1,deep[N];
void add_edge(int from,int to,int dis)
{
    edge[++pos].next=head[from];
    edge[pos].to=to;
    edge[pos].dis=dis;
    head[from]=pos;
}
void add(int from,int to,int dis)
{
    add_edge(from,to,dis);
    add_edge(to,from,0);
}
bool bfs(int s,int t)///分層求depp深度
{
    memset(deep,0);
    queue<int>que;
    deep[s]=1;
    que.push(s);
    while(!que.empty())
    {
        int now=que.front();
        que.pop();
        for(int i=head[now]; i!=-1; i=edge[i].next)//dis在此處用來做標記 是正圖還是返圖
        {
            int v=edge[i].to,dis=edge[i].dis;
            if(!deep[v]&&dis)
            {
                deep[v]=deep[now]+1;
                que.push(v);
            }
        }
    }
    return (deep[t]?true:false);
}
///limit爲s到t的最小邊權,會被不斷約束縮小
int dfs(int now,int t,int limit)///dfs尋找多條增廣路,增加流量,可反悔,
{
    if(!limit || now==t)
        return limit;
    int flow=0,f;
    for(int i=head[now]; i!=-1; i=edge[i].next)
    {
        int v=edge[i].to,dis=edge[i].dis;
        if(deep[v]==deep[now]+1&&(f=dfs(v,t,min(limit,dis))))
        {
            flow+=f;
            limit-=f;
            edge[i].dis-=f;
            edge[i^1].dis+=f;
            if(!limit)
                break;
        }
    }
    return flow;
}
int Dinic(int s,int t)
{
    int ans=0;
    while(bfs(s,t))
        ans+=dfs(s,t,inf);
    return ans;
}


signed main()
{
    IOS;
    file();
    int t;
    cin>>t;
    while(t--)
    {
        memset(head,-1);
        memset(deep,0);
        pos=-1;
        int n,m,k;
        cin>>n>>m>>k;
        map<int,int>ma;
        for(int i=0;i<n;i++)
        {
            int x;
            cin>>x;
            ma[x]++;
        }
        for(auto it:ma)
        {
            add(0,it.F,it.S);
        }
        int cnt=k;
        while(m--)
        {
            int tag,c;
            cin>>tag>>c;
            if(tag==1)
            {
                int a0,b0;
                cin>>a0>>b0;
                add(a0,b0,c);
            }
            else if(tag==2)
            {
                int a1,a2,b1;
                cin>>a1>>a2>>b1;
                int from=cnt+1;
                cnt++;
                for(int i=a1;i<=a2;i++)
                    add(i,from,inf);
                add(from,b1,c);
            }
            else if(tag==3)
            {
                int a1,b1,b2;
                cin>>a1>>b1>>b2;
                int from=cnt+1;
                cnt++;
                add(a1,from,c);
                for(int i=b1;i<=b2;i++)
                    add(from,i,inf);
            }
            else
            {
                int a1,a2,b1,b2;
                cin>>a1>>a2>>b1>>b2;
                int from=cnt+1,to=cnt+2;
                cnt+=2;
                for(int i=a1;i<=a2;i++)
                    add(i,from,inf);
                add(from,to,c);
                for(int i=b1;i<=b2;i++)
                    add(to,i,inf);
            }
        }
        cout<<Dinic(0,k)<<endl;

    }





    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章