QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#599442#5145. Shortest Pathalexz1205TL 67ms255048kbC++144.2kb2024-09-29 04:49:312024-09-29 04:49:33

Judging History

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

  • [2024-09-29 04:49:33]
  • 评测
  • 测评结果:TL
  • 用时:67ms
  • 内存:255048kb
  • [2024-09-29 04:49:31]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

const int N = 2e3+5, MOD = 998244353, M = 5e3;

typedef long long int lint;

lint mat[N][4*N][2];
lint edges[M][3];

vector<array<lint, 2>> con[N];

void solve(){
	memset(mat, 0, sizeof(mat));
	lint n, m, X;
	scanf("%lld %lld %lld", &n, &m, &X);
	for (int x = 0; x < n; x ++){
		con[x].clear();
	}
	for (int x = 0; x < m; x ++){
		int a, b, c;
		scanf("%d %d %d", &a, &b, &c);

		a --, b --;
		con[a].push_back({b, c});
		con[b].push_back({a, c});

		edges[x][0] = a;
		edges[x][1] = b;
		edges[x][2] = c;
	}
	for (int c = 0; c < 2; c ++){
		queue<array<lint, 2>> que;

		if (c == 0) que.push({0, 0});
		else que.push({n-1, 0});

		while (!que.empty()){
			array<lint, 2> cur = que.front();
			que.pop();
			lint i = cur[0], t = cur[1];
			if (t == 4*n){
				continue;
			}
			for (array<lint, 2> e: con[i]){
				int j = e[0];
				if (!mat[j][t+1][c]){
					mat[j][t+1][c] = mat[i][t][c] + e[1];
					que.push({j, t+1});
				}else {
					mat[j][t+1][c] = min(mat[j][t+1][c], mat[i][t][c] + e[1]);
				}
			}
		}
		//for (int x = 0; x < n; x ++){
			//for (int y = 0; y <= 4*n; y ++){
				//printf("%lld ", mat[x][y][c]);
			//}
			//printf("\n");
		//}
		//cout << "------------------" << endl;
	}
	lint sum = 0;
	for (int x = 0; x <= min(4*n, X); x ++){
		sum += mat[n-1][x][0];
		sum %= MOD;
	}

	array<lint, 4> bestE = {(lint)1e18, (lint)1e18, 0, 0};
	array<lint, 4> bestO = {(lint)1e18, (lint)1e18, 0, 0};
	for (int x = 0; x < m; x ++){
		{
			int a = edges[x][0], b = edges[x][1];
			lint c = edges[x][2];
			lint dist1O = 1e18;
			lint dist1E = 1e18;
			lint dist2O = 1e18;
			lint dist2E = 1e18;
			for (int i = 0; i <= 2*n; i ++){
				if (i & 1){
					if ((a == 0 && i == 0) || mat[a][i][0]) dist1O = min(dist1O, mat[a][i][0] + (2*n-i) * c);
					if ((b == n-1 && i == 0) || mat[b][i][1]) dist2O = min(dist2O, mat[b][i][1] + (2*n-i) * c);
				}else {
					if ((a == 0 && i == 0) || mat[a][i][0]) dist1E = min(dist1E, mat[a][i][0] + (2*n-i) * c);
					if ((b == n-1 && i == 0) || mat[b][i][1]) dist2E = min(dist2E, mat[b][i][1] + (2*n-i) * c);
				}
			}
			bestE = min(bestE, (array<lint, 4>){edges[x][2], dist1E+dist2E, a, b});
			bestE = min(bestE, (array<lint, 4>){edges[x][2], dist1O+dist2O, a, b});

			bestO = min(bestO, (array<lint, 4>){edges[x][2], dist1E+dist2O-edges[x][2], a, b});
			bestO = min(bestO, (array<lint, 4>){edges[x][2], dist1O+dist2E-edges[x][2], a, b});
		}
		{
			int b = edges[x][0], a = edges[x][1];
			lint c = edges[x][2];
			lint dist1O = 1e18;
			lint dist1E = 1e18;
			lint dist2O = 1e18;
			lint dist2E = 1e18;
			for (int i = 0; i <= 2*n; i ++){
				if (i & 1){
					if ((a == 0 && i == 0) || mat[a][i][0]) dist1O = min(dist1O, mat[a][i][0] + (2*n-i) * c);
					if ((b == n-1 && i == 0) || mat[b][i][1]) dist2O = min(dist2O, mat[b][i][1] + (2*n-i) * c);
				}else {
					if ((a == 0 && i == 0) || mat[a][i][0]) dist1E = min(dist1E, mat[a][i][0] + (2*n-i) * c);
					if ((b == n-1 && i == 0) || mat[b][i][1]) dist2E = min(dist2E, mat[b][i][1] + (2*n-i) * c);
				}
			}
			bestE = min(bestE, (array<lint, 4>){edges[x][2], dist1E+dist2E, a, b});
			bestE = min(bestE, (array<lint, 4>){edges[x][2], dist1O+dist2O, a, b});

			bestO = min(bestO, (array<lint, 4>){edges[x][2], dist1E+dist2O-edges[x][2], a, b});
			bestO = min(bestO, (array<lint, 4>){edges[x][2], dist1O+dist2E-edges[x][2], a, b});
		}
	}
	//printf("%lld %lld %lld %lld\n", bestO[0], bestO[1], bestO[2], bestO[3]);
	//printf("%lld %lld %lld %lld\n", bestE[0], bestE[1], bestE[2], bestE[3]);
	{
		// insert funny math stuff
		lint s = (X-4*n);
		if (s > 0){
			if (bestE[1] < 1e18){
				bestE[0] %= MOD;
				bestE[1] %= MOD;
				lint c = s/2;
				c %= MOD;
				sum += c * bestE[1];
				sum %= MOD;
				sum += ((c)*(c+1)/2) % MOD * 2*bestE[0] % MOD;
				sum %= MOD;
			}
			if (bestO[1] < 1e18) {
				bestO[0] %= MOD;
				bestO[1] %= MOD;
				lint c = (s+1)/2;
				c %= MOD;
				sum += c * bestO[1];
				sum %= MOD;
				sum += ((c)*(c+1)/2) % MOD * 2*bestO[0] % MOD;
				sum %= MOD;
			}
		}
	}
	printf("%lld\n", sum);
}

int main(){
	int n;
	scanf("%d", &n);
	for (int x = 0; x < n; x ++){
		solve();
	}
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 67ms
memory: 255048kb

input:

4
3 2 10
1 2 5
2 3 4
3 0 1000000000
3 3 100
1 2 3
1 3 4
2 3 5
4 6 1000000000
1 2 244
1 2 325
1 4 927
3 3 248
2 4 834
3 4 285

output:

125
0
15300
840659991

result:

ok 4 number(s): "125 0 15300 840659991"

Test #2:

score: -100
Time Limit Exceeded

input:

400
4 7 850187899
1 2 83
1 2 24
3 1 23
2 3 80
3 3 65
1 2 55
2 4 31
4 7 297586795
3 4 54
1 1 66
2 2 75
1 3 68
1 4 27
1 4 29
2 3 96
5 7 217277444
3 3 9
3 4 36
2 2 77
5 5 38
3 3 6
1 2 18
1 2 23
5 6 379032278
5 5 96
4 3 92
3 2 49
4 3 44
1 4 19
1 1 18
5 6 534284598
5 1 59
1 2 2
3 3 55
2 2 24
5 4 34
2 4 7...

output:


result: