QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#576026#9315. Rainbow Bracket SequenceswimsealTL 1ms7764kbC++143.2kb2024-09-19 18:00:132024-09-19 18:00:13

Judging History

你现在查看的是最新测评结果

  • [2024-09-19 18:00:13]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:7764kb
  • [2024-09-19 18:00:13]
  • 提交

answer

#include <bits/stdc++.h>

#define x first
#define y second
#define pb push_back
#define int long long 

using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<double, double> PDD;
 
const int N = 1E3 + 10, M = 2E5 + 10, INF = 1e9;
const int MOD = 1e9 + 7;
const LL LINF = 1e18;
const double eps = 1e-9;

int n, m, S, T;
int h[N], e[M], ne[M], w[M], f[M], idx;
int hd[N];//预处理建立虚拟远点到所有的点的距离
int d[N], pre[N], incf[N];
bool st[N];

void add(int a, int b, int c, int d){
    e[idx] = b, f[idx] = c, w[idx] =  d, ne[idx] = h[a], h[a] = idx ++;
    e[idx] = a, f[idx] = 0, w[idx] = -d, ne[idx] = h[b], h[b] = idx ++;

}

void spfa(){
	queue<int> q;
	memset(st, 0, sizeof st);
	memset(hd, 0x3f, sizeof hd);

	
	q.push(S), hd[S] = 0, st[S] = true;
	
	while(q.size()){
		int t = q.front();
		q.pop();
		st[t] = false;
		
		for (int i = h[t]; ~i; i = ne[i]){
			int j = e[i];

			if(hd[j] > hd[t] + w[i] && f[i]){
				hd[j] = hd[t] + w[i];

				if(!st[j]){
					st[j] = true;
					q.push(j);
				}
			} 
		}
	}
}

bool dijkstra(){
	//将上一次的dist加到hd里面
	for (int i = 1; i <= n; i ++)
		if(d[i] != 0x3f3f3f3f)
			hd[i] += d[i];
	memset(st, 0, sizeof st);
	memset(d, 0x3f, sizeof d);
    memset(incf, 0, sizeof incf);

	priority_queue<pii, vector<pii>, greater<pii>> q; 
	q.push({0,S}), d[S] = 0, incf[S] = INF;

	while(q.size()){
		auto [_,u] = q.top();
		q.pop();

		if(st[u]) continue;
		st[u] = true;

		for (int i = h[u]; ~i; i = ne[i]){
			int v = e[i];
			int nw = w[i] + hd[u] - hd[v];

			if(f[i] && d[v] > d[u] + nw){
				d[v] = d[u] + nw;
				pre[v] = i;
				incf[v] = min(incf[u], f[i]);
				q.push({d[v], v});
			}
		}
	}
	return incf[T] > 0;
}

void FEK(int& flow, int& cost){	
	//预处理虚拟原点到每个点的距离
	spfa();
	//for (int i = 1 ; i <= n ; i ++) cout << hd[i] << endl;

	flow = cost = 0;
	while(dijkstra()){
		int t = incf[T];
		flow += t;
		//利用和
		cost += (d[T] + hd[T] - hd[S]) * t;

		
		for(int i = T; i != S; i = e[pre[i] ^ 1]){
            f[pre[i]] -= t;
            f[pre[i] ^ 1] += t;
        }

	}
}

int c[N], v[N], l[N];

void solve(){
	cin >> n >> m;
	S = 0, T = n * 2 + m + 10;

	idx = 0;
	memset(h, -1, sizeof h);
	memset(hd, -1, sizeof hd);
	LL mi = 0, ans = 0, sum = 0;
	for (int i = 1; i <= m; i ++){
		cin >> l[i];
		sum += l[i];
	}
	for (int i = 1; i <= n * 2; i ++)cin >> c[i];
	for (int i = 1; i <= n * 2; i ++)cin >> v[i];
	
	if(sum > n){
		cout << "-1" << '\n';
		return;
	}


	for (int i = 1; i < n * 2; i ++){
		add(i, i + 1, (i + 1) / 2, - INF);
		add(i, i + 1, n, 0);
		mi -= 1ll * (i + 1) / 2 * INF;
		
	}

	add(2 * n, T, n, 0);
	for (int i = 1; i <= m; i ++){
		add(S, 2 * n + i, l[i], -INF);
		add(S, 2 * n + i, n, 0);
		mi += 1ll*l[i] * (- INF);
	}

	for (int i = 1; i <= 2 * m; i ++)
		add(2 * n + c[i], i, 1, -v[i]);
	
	int flow, cost;
	FEK(flow, cost);
	if(cost > mi) cout << "-1" << '\n';
	else cout << -(cost - mi) << '\n';
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t = 1;cin >>t;
	while(t --) solve();
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 7764kb

input:

2
3 2
1 2
1 2 2 2 1 2
3 1 4 2 2 1
3 2
2 2
1 2 2 2 1 2
3 1 4 2 2 1

output:

9
-1

result:

ok 2 number(s): "9 -1"

Test #2:

score: -100
Time Limit Exceeded

input:

50
8 6
0 2 2 0 3 1
3 5 1 1 5 3 5 2 3 2 2 1 2 2 4 6
998133227 879226371 59632864 356493387 62611196 827258251 296576565 204244054 812713672 780267148 614679390 447700005 102067050 544546349 116002772 761999375
1 1
1
1 1
343766215 374461155
3 1
2
1 1 1 1 1 1
796323508 303640854 701432076 853325162 610...

output:


result: