题意:
就是给你n个点和m条边,每个点有个权值,每次可以选择一个起点和终点然后这条路径和可以重复覆盖某些边,使得每条边被覆盖奇数次,使得这些路径权值和最小。权值就是起点和终点的权值之积。
思考:
刚开始发现好像不是那么好做,但是感觉这种题就是读懂题之后的一种贪心模型罢了。其实说,让每个边经过的次数都是奇数,如果直接乱弄肯定没法做,其实可以想象一下,如果没有度为奇数的点,那么肯定有一个欧拉路,所以直接从i点走到i点就行了。如果有奇数点呢,那么肯定有偶数个,因为度 = 2*边,度是偶数。所以奇数是成对出现的。那么让奇数点和奇数点互相配对就行了,怎么最贪心呢?肯定是从小到大排序后,小的和大的×即可。
代码:
int T,n,m,k;
int va[N];
int in[N];
vector<int > e[N];
signed main()
{
IOS;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>va[i];
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
e[a].pb(b);
e[b].pb(a);
in[a]++;in[b]++;
}
vector<int > v;
for(int i=1;i<=n;i++) if(in[i]&1) v.pb(va[i]);
if(v.size()==0)
{
int minn = inf;
for(int i=1;i<=n;i++)
minn = min(minn,va[i]*va[i]);
cout<<minn%mod;
}
else
{
int minn = 0;
sort(v.begin(),v.end());
for(int i=0;i<v.size()/2;i++)
minn = (minn+v[i]*v[v.size()-i-1])%mod;
minn = (minn%mod+mod)%mod;
cout<<minn%mod;
}
return 0;
}
总结:
多多思考,对于好多这种题,无非就是欧拉图之类的性质。