[CSP-S模拟测试]:壕游戏(费用流)

题目传送门(内部题18)


输入格式

第一行包括四个数$n,m,k,s$表示有$n$个剧情点,$m$个关卡,要玩$k$次游戏,$s$个完结点接下来一行包含$s$个数,代表$s$个完结点的编号。
接下来$m$行,每行五个正整数$x_i,y_i,A_i,B_i,C_i$,代表第$i$号关卡从$x_i$号剧情点连向$y_i$号剧情点,$A_i,B_i,C_i$意义如题目描述。


输出格式

如果不能通关输出$-1$,否则输出一个整数,代表至少需要的软妹币值。


样例

样例输入:

6 8 2 2
4 5
1 2 4 0 2
1 3 5 0 2
3 4 1 5 1
2 5 1 0 1
4 6 4 2 2
5 6 0 4 2
1 5 5 9 2
2 6 4 5 2

样例输出:

16


数据范围与提示

样例解释:

第一次从$1−>2−>5$,费用为$5$。
第二次从$1−>3−>4$,费用为$11$。

数据范围:

对于$30\%$的数据,$A_i=0$。
对于另外$20\%$的数据,游戏为一条链。
对于$100\%$的数据,$1\leqslant n\leqslant 1,000,1\leqslant m\leqslant 20,000,1\leqslant k\leqslant 200,A_i,B_i\geqslant 0,1\leqslant C_i\leqslant k$。
保证答案在$int$范围内。


题解

注意到$k$只有200,但是又有谁能想到是费用流呢?

实际上,我的思路和题解稍有偏差。

建边的时候记录上边的$A,B$,每走一次就让花费增加,退流的时候再剪掉就好了,缺点就是每次只能流一个,不然有可能会错过最优答案。

时间复杂度:$\Theta(m\times k+n\times k^2)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include
using namespace std;
struct rec
{
	int nxt;
	int to;
	int w;
	int f;
	int a;
}e[100001];
int head[5001],cnt=1;
int n,m,k,s;
int S,T;
int que[100001],pre[50001],dis[50001];
bool vis[50001];
int ans;
void add(int x,int y,int w,int f,int a)
{
	e[++cnt].nxt=head[x];
	e[cnt].to=y;
	e[cnt].w=w;
	e[cnt].f=f;
	e[cnt].a=a;
	head[x]=cnt;
}
bool bfs()
{
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[S]=0;
	vis[S]=1;
	int he=1,ta=1;
	que[ta]=S;
	while(he<=ta)
	{
		for(int i=head[que[he]];i;i=e[i].nxt)
			if(e[i].w&&dis[que[he]]+e[i].f

rp++

转载于:https://www.cnblogs.com/wzc521/p/11447008.html

你可能感兴趣的:([CSP-S模拟测试]:壕游戏(费用流))