Codeforces 703B Mishka and trip

来源:互联网 发布:淘宝旺铺有什么好处 编辑:程序博客网 时间:2024/06/06 01:04

题意:有n个城市,编号为1~n,相邻的两个城市之间有一条路,路的权值是两个端点城市的权值的乘积,在这n个城市中选出k个中心城市,中心城市与其余的所有城市之间都有一条路径,求整张地图所有路径的权值和

解题思路:模拟.如果直接枚举相邻两个城市间的路径会超时。可以用a[k]*a[1]+a[k]*a[2]+a[k]*a[3]+...=a[k]*(a[1]+a[2]+a[3]+...),求出n个城市的权值和和k个中心城市的权值和,如果i是普通城市,就要与与它相邻的两个城市和中心城市的权值和相乘,这时还要判断与它相邻的两座城市里有没有中心城市,如果有的话要减掉,避免算重复了,如果i是中心城市,直接乘以除了它本身以外的所有城市的权值和即可,最后的总和要除以2,因为每条路都算了两遍,注意要用long long,否则会WA

代码:

#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <cstdio>using namespace std;typedef long long ll;int main(){    ll n,k;    while(scanf("%I64d%I64d",&n,&k)==2)    {        ll a[100005],kk[100005];        ll sum=0,sumk=0;        for(ll i=0; i<n; i++)        {            scanf("%I64d",&a[i]);            sum+=a[i];        }        for(ll i=0; i<k; i++)        {            scanf("%I64d",&kk[i]);            kk[i]--;            sumk+=a[kk[i]];        }        ll temp=0,ans=0;        for(ll i=0,j=0; i<n; i++)        {             ll p,q;             if(i==0){p=n-1;q=1;}             else if(i==n-1){p=n-2;q=0;}             else {p=i-1;q=i+1;}             if(i==kk[j])             {                 temp=sum-a[i];                 j++;             }             else             {                 temp=a[p]+a[q]+sumk;                 int pos1=lower_bound(kk,kk+k,p)-kk;                 if(kk[pos1]==p)temp-=a[p];                 int pos2=lower_bound(kk,kk+k,q)-kk;                 if(kk[pos2]==q)temp-=a[q];             }             ans+=a[i]*temp;        }        printf("%I64d\n",ans/2);    }    return 0;}


原创粉丝点击