Solution to a problem Luogu P3959 [Treasure

To a not-so-slow-like pressure? ? ?

Saying that there is no problem purple question difficulty of it, then the data is also water


A look at the data size, n ≤ 12 n- . 1 2, decisively shaped pressure.

Then starting point to enumerate, is located dp d the p-state:

f [i] [j] = i to j as a starting point to a minimum cost state

Wherein J J is a binary number (expressed as a decimal) of I I bit . 1 1 0 whether 0 has been reached respectively a first I I point ( . 1 1 denotes has been reached, 0 0 means has not reached)

(Since m large m, n- n-small, there will be multiple edges, the adjacency matrix ( E [U] [V] E [ U ] [ V ]))

Whereby the state transition equation can be listed:

f[i][j]=min{f[i][k]+diss[i][k][u]*e[u][v]}

(j&(1<<(u-1))!=0,j&(1<<(v-1))!=0,i!=v,k=j^(1<<(v-1)),e[u][v]!=1e9)

( E [U] [V]! = 1E9 E [ U ] [ V ] ! = . 1 E . 9 is said U U, V bordered between v)

What does this mean? That we find a state ( k k) than the current state ( j j) only a few points (obviously can not be the starting point), then from k k to j expand j, in all of k take the least expensive kind of k, .

But there is a problem, take the side of how to count?

The subject description, it is the starting point to the side length multiplied by u points u elapsed ( DIS [I] [J] [u] D I S [ I ] [ J ] [ u ]) to.

The problem again, DIS [i] [J] [U] d i S [ i ] [ J ] [ U ] how to count?

Every time the state transition of the way to divert

code show as below:

#include<cstdio>

inline int read(){
	int r=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')r=(r<<1)+(r<<3)+c-'0',c=getchar();
	return r*f;
}

int n,ans=1e9,m,f[15][5005],e[15][15],dis[15][5005][15];

inline int min(int a,int b){
	return a<b?a:b;
}

int main(){
	freopen("treasure.in","r",stdin);
	freopen("treasure.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			e[i][j]=1e9;
	for(int i=1;i<=m;i++){
		int u=read(),v=read();
		if(u-v)e[u][v]=e[v][u]=min(e[u][v],read());
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<1<<n;j++)
			f[i][j]=1e9;
	for(int i=1;i<=n;i++){
		f[i][1<<(i-1)]=0;
		dis[i][1<<(i-1)][i]=1;
		for(int j=(1<<(i-1))+1;j<1<<n;j++){
			if(!(j&(1<<(i-1))))continue;
			int x=j,u=1;
			while(x){
				if(x&1){
					for(int v=1;v<=n;v++){
						if(i==v||e[u][v]==1e9||!(j&(1<<(v-1))))continue;
						int k=j^(1<<(v-1));
						if(f[i][j]>f[i][k]+dis[i][k][u]*e[u][v]){
							f[i][j]=f[i][k]+dis[i][k][u]*e[u][v];
							for(int y=1;y<=n;y++)dis[i][j][y]=dis[i][k][y];
							dis[i][j][v]=dis[i][k][u]+1;
				To ++;
				}
					}
						}
				x>>=1;
			}
		}
		ans=min(ans,f[i][(1<<n)-1]);
	}
	printf("%d",ans);
	return 0;
}

  

Guess you like

Origin www.cnblogs.com/wyzwyz/p/11542904.html