首页 > 其他分享 >POI2011PRO-Programming Contest

POI2011PRO-Programming Contest

时间:2024-04-20 16:57:45浏览次数:27  
标签:mf return Contest int Programming flow ret POI2011PRO dep

POI #Year2011 #Dinic #网络流 #贪心

容易想到拆点的费用流做法,但是二分再拆点的时间复杂度是不可接受的

考虑因为每个的时间 \(r\) 是定值,所以不可能出现做题个数差超过 \(1\) 的情况

所以每一轮每个分配一个,用 \(Dinic\) 在推进一次,知道满流

// Author: xiaruize
const int N = 1e6 + 10;

struct MF
{
	struct edge
	{
		int v, nxt, cap, flow;
	} e[N];

	int fir[N], cnt = 0;

	int n, S, T;
	int maxflow = 0;
	int dep[N], cur[N];

	void init()
	{
		// cerr << "flag" << endl;
		memset(fir, -1, sizeof(fir));
		cnt = 0;
	}

	void addedge(int u, int v, int w)
	{
		e[cnt] = {v, fir[u], w, 0};
		fir[u] = cnt++;
		e[cnt] = {u, fir[v], 0, 0};
		fir[v] = cnt++;
	}

	bool bfs()
	{
		queue<int> q;
		memset(dep, 0, sizeof(int) * (n + 1));

		dep[S] = 1;
		q.push(S);
		while (q.size())
		{
			int u = q.front();
			q.pop();
			for (int i = fir[u]; ~i; i = e[i].nxt)
			{
				int v = e[i].v;
				if ((!dep[v]) && (e[i].cap > e[i].flow))
				{
					dep[v] = dep[u] + 1;
					q.push(v);
				}
			}
		}
		return dep[T];
	}

	int dfs(int u, int flow)
	{
		if ((u == T) || (!flow))
			return flow;

		int ret = 0;
		for (int &i = cur[u]; ~i; i = e[i].nxt)
		{
			int v = e[i].v, d;
			if ((dep[v] == dep[u] + 1) && (d = dfs(v, min(flow - ret, e[i].cap - e[i].flow))))
			{
				ret += d;
				e[i].flow += d;
				e[i ^ 1].flow -= d;
				if (ret == flow)
					return ret;
			}
		}
		return ret;
	}

	void dinic()
	{
		while (bfs())
		{
			memcpy(cur, fir, sizeof(int) * (n + 1));
			maxflow += dfs(S, INF);
			// cerr << maxflow << endl;
		}
	}
} mf;

int n, m, r, t, k;
int cnt[N];
pii eg[N];

void solve()
{
	mf.init();
	mf.S = 0;
	cin >> n >> m >> r >> t >> k;
	mf.T = mf.n = n + m + 1;
	rep(i, 1, k)
	{
		cin >> eg[i].first >> eg[i].second;
		mf.addedge(eg[i].second, eg[i].first + m, INF);
	}
	rep(i, 1, m)
	{
		mf.addedge(0, i, 1);
	}
	int res = 0;
	for (int i = 1; mf.maxflow < m && i * r <= t; i++)
	{
		int la = mf.maxflow;
		rep(i, 1, n) mf.addedge(i + m, n + m + 1, 1);
		mf.dinic();
		res += (mf.maxflow - la) * i * r;
	}
	cout << mf.maxflow << ' ' << res << endl;
}

#ifndef ONLINE_JUDGE
bool end_of_memory_use;
#endif

signed main()
{
	// freopen(".in","r",stdin);
	// freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int testcase = 1;
	// cin >> testcase;
	while (testcase--)
		solve();
#ifndef ONLINE_JUDGE
	cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl;
	cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl;
#endif
	return 0;
}

标签:mf,return,Contest,int,Programming,flow,ret,POI2011PRO,dep
From: https://www.cnblogs.com/xiaruize/p/18147875

相关文章

  • The 18th Zhejiang Provincial Collegiate Programming Contest
    目录写在前面AMLCIJFGD写在最后写在前面比赛地址:https://codeforces.com/gym/103055。以下按个人难度向排序。唐唐唐唐唐,又是死在数学手上的一次。妈的为什么上个大学这么累好相似A签到。///*By:Luckyblock*/#include<bits/stdc++.h>#defineLLlonglong//=======......
  • AtCoder Beginner Contest 319
    A-LegendaryPlayers#include<bits/stdc++.h>usingnamespacestd;intmain(){map<string,string>h;h["tourist"]="3858";h["ksun48"]="3679";h["Benq"]="3658"......
  • [题解](A-G)Atcoder Educational DP Contest(更新中)
    AtcoderEducationalDPContest\(\textbf{A.Frog1}\)对于一块石头\(i(3\lei\leN)\),\(i-1\)和\(i-2\)均能到达。用\(f[i]\)表示跳到第\(i\)个石头用的最小体力消耗:\[f[i]=min(abs(h[i]-h[i-1])+f[i-1],abs(h[i]-h[i-2])+f[i-2])\qquadi\ge3\]时间复杂度\(O(n)\)。......
  • AtCoder Beginner Contest 347
    B-Substring难度:⭐题目大意给你一个由小写英文字母组成的字符串S;请问S有多少个不同的非空子串?解题思路数据很小,暴力就行;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#defi......
  • AtCoder Beginner Contest 346
    B-Piano难度:⭐⭐题目大意现有S为无限重复字符串"wbwbwwbwbwbw"形成的字符串。请问S中是否存在由W次出现的'w'和B次出现的'b'组成的子字符串T;解题思路字符串T显然可以由S的一段后缀+若干个S+S的一段前缀组成;但是,这个题的W和B都最大为100;也就是说,如果存......
  • [ABC349] AtCoder Beginner Contest 349 题解
    [ABC349]AtCoderBeginnerContest349题解目录[ABC349]AtCoderBeginnerContest349题解A-ZeroSumGameB-CommencementC-AirportCodeD-DivideIntervalE-WeightedTic-Tac-ToeF-SubsequenceLCMG-PalindromeConstruction总结A-ZeroSumGame零和博弈,......
  • AtCoder Beginner Contest 349
    B-Commencement难度:⭐题目大意给定一个字符串,问这个字符串中出现的字母是否都恰好为0个或者2个;解题思路数据很小,暴力就行;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#def......
  • The 2023 ICPC Asia Hong Kong Regional Programming Contest (The 1st Universal Cup
    Preface不知道VP什么就继续找往年的区域赛真题来打了这场题挺合我们队口味的,开场2h就开出了5题(徐神110min的时候就过相对最难的C题),而且手上还有3个会写的题最后中间虽然因为F题卡常(CF评测机太慢导致的)浪费了快1h时间,但索性时间剩余很多还是4h下班了后面的题感觉都不太可做,遂光......
  • AtCoder Beginner Contest 349
    A-ZeroSumGame(abc349A)题目大意\(n\)个人游戏,每局有一人\(+1\)分,有一人\(-1\)分。给定最后前\(n-1\)个人的分数,问第\(n\)个人的分数。解题思路零和游戏,所有人总分是\(0\),因此最后一个人的分数就是前\(n-1\)个人的分数和的相反数。神奇的代码n=input()prin......
  • AtCoder Beginner Contest 347
    A-Divisible#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=longlong;#defineinti64usingvi=vector<i64>;usingpii=pair<int,int>;usingpiii=tuple<int,int,int>;constintinf=1e......