NOI Online #1 Starter Group T3 Magic

Original title link

Concise title

Find the shortest path, you can put the middle at most kkThe right of k roads is changed to negative.

analysis:

It can be found that this question nnThe range of n is very small, you can usefloyd floydf l o y d to do it. floyd floydf l o y d find the shortest path on one side,d (i, j) = min ⁡ (d (i, k) + d (k, j)) d(i,j)=\min(d(i,k) +d(k,j))d(i,j)=min ( d ( i ,k)+d(k,j ) ) , after we find the shortest path, consider adding magic. Letf (i, j, p) f(i,j,p)f(i,j,p ) isiii tojjj usesppThe shortest path of p magic. A road can be changed to negative, then there is a state transition equation f (i, j, p) = min ⁡ (f (i, u, x) − edge (u, v) + f (v, j, y ), x + y = p) f(i,j,p)=\min(f(i,u,x)-edge(u,v)+f(v,j,y),x+y=p )f(i,j,p)=min ( f ( i ,u ,x)e d g e ( u ,v )+f(v,j,and ) ,x+Y=p ) Such a state transition equation space is not enough, and a four-level loop must be enumerated. If it is changed to a rolling array,f (i, j) f(i,j)f(i,j ) meansiii tojjThe shortest path of j . Regardless of how many times the magic is used, then: f (i, j) = min ⁡ (f (i, u) − edge (u, v) + f (v, j)) f(i,j)=\min (f(i,u)-edge(u,v)+f(v,j))f(i,j)=min ( f ( i ,u )e d g e ( u ,v )+f(v,j ) ) So, let's consider usingkkK times magic problem. Obviously, each iteration will choose an edge to use magic or not, and not choosing will only be the optimal solution, so iteratekkk times is at mostkkK- time magic solution. But this space is enough, but the time is still not enough, there is still a four-layer cycle.
Consider re-optimization, so calculatekkK times, and this one uses magic every time you choose the side, but it doesn’t matter which side you choose first, so the associative law is satisfied. Then if the associative law is satisfied, it can be solved with fast power. Becausefff is a two-dimensional array, you can use a method similar to matrix multiplication to findmin ⁡ \minmin is fine. In this way, first calculate the solution using magic once, and then quickly exponentiate it to usekkk times plan.
The time complexity of fast power isΘ (n 3 log ⁡ n) \Theta(n^3\log n)Θ ( n3logn ) ,dp dp infrontd p find the shortest path isΘ (n 3) \Theta(n^3)Θ ( n3 ),dp dpd p The time complexity of finding a magic isΘ (n 2 m) \Theta(n^2m)Θ ( n2 m), the total time complexity isΘ (n 3 log ⁡ n + n 2 m) \Theta(n^3\log n+n^2m)Θ ( n3logn+n2 m)

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int NN=104;
int n,m,k;
ll d[NN][NN],f[NN][NN];
struct node
{
    
    
	int u,v,w;
}edge[2504];
void mul(ll c[][NN],ll a[][NN],ll b[][NN])
{
    
    
	ll t[NN][NN];
	memset(t,0x3f,sizeof(t));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			for(int k=1;k<=n;k++)
				t[i][j]=min(t[i][j],a[i][k]+b[k][j]);
	memcpy(c,t,sizeof(t));
}
ll ksm()
{
    
    
	while(k)
	{
    
    
		if(k&1)
			mul(d,d,f);
		mul(f,f,f);
		k>>=1;
	}
	return d[1][n];
}
int main()
{
    
    
	scanf("%d%d%d",&n,&m,&k);
	memset(d,0x3f,sizeof(d));
	for(int i=1;i<=n;i++)
		d[i][i]=0;
	for(int i=0;i<m;i++)
	{
    
    
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		edge[i]=(node){
    
    u,v,w};
		d[u][v]=min(d[u][v],1ll*w);
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
	memcpy(f,d,sizeof(f));
	for(int k=0;k<m;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				f[i][j]=min(f[i][j],d[i][edge[k].u]-edge[k].w+d[edge[k].v][j]);
	printf("%lld",ksm());
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44043668/article/details/108811073