首页 > 代码库 > 【BZOJ 1119】 1119: [POI2009]SLO (置换)

【BZOJ 1119】 1119: [POI2009]SLO (置换)

1119: [POI2009]SLO

Description

对于一个1-N的排列(ai),每次你可以交换两个数ax与ay(x<>y),代价为W(ax)+W(ay) 若干次交换的代价为每次交换的代价之和。请问将(ai)变为(bi)所需的最小代价是多少。

Input

第一行N。第二行N个数表示wi。第三行N个数表示ai。第四行N个数表示bi。 2<=n<=1000000 100<=wi<=6500 1<=ai,bi<=n ai各不相等,bi各不相等 (ai)<>(bi) 样例中依次交换数字(2,5)(3,4)(1,5)

Output

一个数,最小代价。

Sample Input

6
2400 2000 1200 2400 1600 4000
1 4 5 3 6 2
5 3 2 4 6 1

Sample Output

11200

HINT

感谢MT大牛贡献译文.

 

 

【分析】

  跟BZOJ 1119一模一样,记得用LL。

 

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define Maxn 1000010
 8 #define INF 0xfffffff
 9 #define LL long long
10 
11 LL w[Maxn];
12 
13 struct node
14 {
15     LL a,b;
16 }t[Maxn];
17 
18 bool cmp(node x,node y) {return x.a<y.a;}
19 LL mymin(LL x,LL y) {return x<y?x:y;}
20 
21 bool vis[Maxn];
22 
23 int main()
24 {
25     LL n,mnn=INF;
26     scanf("%lld",&n);
27     for(LL i=1;i<=n;i++) {scanf("%lld",&w[i]);mnn=mymin(mnn,w[i]);}
28     for(LL i=1;i<=n;i++) scanf("%lld",&t[i].a);
29     for(LL i=1;i<=n;i++) scanf("%lld",&t[i].b);
30     sort(t+1,t+1+n,cmp);
31     memset(vis,0,sizeof(vis));
32     LL ans=0;
33     for(LL i=1;i<=n;i++) if(vis[i]==0)
34     {
35         LL x=i,mn=INF,h=0;
36         LL cnt=0;
37         while(vis[x]==0)
38         {
39             mn=mymin(mn,w[x]);
40             vis[x]=1;
41             cnt++;
42             h+=w[x];
43             x=t[x].b;
44         }
45         ans+=mymin(h+(cnt-2)*(LL)mn,h+mn+(cnt+1)*(LL)mnn);
46     }
47     printf("%lld\n",ans);
48     return 0;
49 }
View Code

 

2017-01-12 20:13:51

【BZOJ 1119】 1119: [POI2009]SLO (置换)