QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#225877#5458. Shortest Path QueryZSH_ZSH#TL 0ms3876kbC++142.2kb2023-10-25 11:05:482023-10-25 11:05:48

Judging History

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

  • [2023-10-25 11:05:48]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3876kb
  • [2023-10-25 11:05:48]
  • 提交

answer

#include<bits/stdc++.h>
#define rep(i,a,b) for (register int i=(a);i<=(b);i++)
#define drep(i,a,b) for (register int i=(a);i>=(b);i--)
typedef long long ll;
using namespace std;

vector<array<int,2> > minkowski(vector<array<int,2> > &a,vector<array<int,2> > &b)
{
	if (!a.size()) return b;
	if (!b.size()) return a;
	
	vector<array<int,2> > c(a.size()+b.size());
	{
		int i=0,j=0;
		while (i<a.size()||j<b.size())
		{
			if (j==b.size()) c[i+j]=a[i],i++;
			else if (i==a.size()) c[i+j]=b[j],j++;
			else
			{
				if (a[i][0]<b[j][0]||(a[i][0]==b[j][0]&&a[i][1]<b[j][1])) c[i+j]=a[i],i++;
				else c[i+j]=b[j],j++;
			}
		}
	}
	
	vector<array<int,2> > stk;
	for (auto x:c)
	{
		if (stk.size()&&x[0]==stk.back()[0]&&x[1]>=stk.back()[1]) continue;
		while (stk.size()>1)
		{
			auto a=stk[stk.size()-2],b=stk.back();
			array<int,2> u={x[0]-a[0],x[1]-a[1]};
			array<int,2> v={b[0]-a[0],b[1]-a[1]};
			if (1ll*u[0]*v[1]-1ll*u[1]*v[0]>=0)
			{
				stk.pop_back();
			}
		}
		stk.push_back(x);
	}
	return stk;
}

int main()
{
	ios::sync_with_stdio(false); cin.tie(0);
	
	int n,m; cin>>n>>m;
	vector<vector<array<int,2> > > G(n+1);
	rep(i,1,m)
	{
		int u,v,w; cin>>u>>v>>w;
		G[v].push_back({u,w});
	}
	
	vector<vector<array<int,2> > > vec(n+1);
	vec[1].push_back({0,0});
	rep(i,2,n)
	{
		queue<vector<array<int,2> > > q;
		for (auto v:G[i]) 
		{
			auto t=vec[v[0]];
			for (auto &x:t)
			{
				if (v[1]==0) x[0]++; 
				else x[1]++;
			}
			q.push(t);
		}
		while (q.size()>=2)
		{
			auto u=q.front(); q.pop();
			auto v=q.front(); q.pop();
			q.push(minkowski(u,v));
		}
		vec[i]=q.front();
	}
	
//	rep(i,1,n)
//	{
//		printf("vec %d : ",i);
//		for (auto x:vec[i]) printf("(%d,%d) ",x[0],x[1]);
//		printf("\n");
//	}
	
	int q; cin>>q;
	rep(_,1,q)
	{
		int a,b,x; cin>>a>>b>>x;
		int l=0,r=vec[x].size()-1;
		while (r-l>3)
		{
			int m1=(l+l+r)/3,m2=(l+r+r)/3;
			ll v1=1ll*a*vec[x][m1][0]+1ll*b*vec[x][m1][1];
			ll v2=1ll*a*vec[x][m2][0]+1ll*b*vec[x][m2][1];
			if (v2>=v1) r=m2;
			else l=m1;
		}
		ll ans=1e18;
		rep(i,l,r) ans=min(ans,1ll*a*vec[x][i][0]+1ll*b*vec[x][i][1]);
		printf("%lld\n",ans);
	}
	
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3876kb

input:

4 4
1 2 0
1 3 1
2 4 0
3 4 1
3
3 5 2
3 2 4
2 3 4

output:

3
4
4

result:

ok 3 number(s): "3 4 4"

Test #2:

score: -100
Time Limit Exceeded

input:

50000 100000
1 2 1
2 3 0
3 4 1
4 5 0
5 6 1
6 7 0
7 8 1
8 9 1
9 10 0
10 11 1
11 12 1
12 13 1
13 14 0
14 15 0
15 16 0
16 17 0
17 18 1
18 19 1
19 20 0
20 21 1
21 22 0
22 23 0
23 24 1
24 25 1
25 26 0
26 27 1
27 28 0
28 29 0
29 30 0
30 31 0
31 32 1
32 33 0
33 34 1
34 35 1
35 36 1
36 37 1
37 38 0
38 39 0
...

output:


result: