TC-SRM617div1-500

来源:互联网 发布:黑马程序员项目 编辑:程序博客网 时间:2024/04/27 23:47

虽然说每次做完TC 官方都会给出很厚道的题解,但是毕竟每个人从中学到的东西不尽相同。因此还是打算写一个这样的题解来做一些不明觉厉的总结以上。


这道题的题意是给出两个数组choice1[]和choice2[],表示对于每个i你可以选择choice1[i]=1 ,choice2[i]=2 或者 choice1[i]=2 ,choice2[i]=1。分别表示给choice1[i]一号奖励并给choice2[i]二号奖励,或者给choice1[i]二号奖励并且给choice2[i]一号奖励。目的是使Σ|number1[p]-number2[p]|最小。其中number1[p]表示的是p所获得的的一号奖励的个数,number2[p]表示的是p所获得的二号奖励的个数。


首先要注意到的是这个题目的决策是具有传递性的。即对于choice1[i],choice2[i],choice1[i+1],choice2[i+1] 如果有 (choice1[i] 或者 choice2[i])==(choice1[i+1] 或者 choice2[i+1])那么其他两个决策是会造成相互影响的。那么我们把这个传递性表示为a-->b  b-->c得出a-->c 那么根据这个传递性 我们为了控制变量就会考虑使得中间变量无关,或者等价无关是否可以做到。然后就参考题解中的神构图了,如果choice1[i]=1 ,choice2[i]=2 则 使得这条边的方向从choice1[i]指向choice2[i]。而number1[choice1[i]]即为其choice1[i]的入度,number2[choice1[i]] 为其出度,对于图上的某一段点开始若该端点的oude[nox]-inde[nox]>=2则对于任意oude[des]<inde[des]为终点的链,将其经过的所有边反向,所得到的的结果必定比原先的结果要优。

因为对于起点而言经过反向 得到的权值是 abs( oude[nox]-1-(inde[nox]+1))

对于中间节点得到的权值是 abs(oude[i]+1-inde[i]-1)

对于终点而言得到的权值是 abs(oude[i]+1-(inde[i]-1))

易得必定解更优。



上图可以转化为




于是本题可解。

即为先按照给出的choice1与choice2构图,找到oude[nox]-inde[nox]>=2或者inde[nox]-oude[nox]>=2的点,之后找到出入度大小关系与之相反的终点,使该路径上所有边反向,知道不存在oude[nox]-inde[nox]>=2或者inde[nox]-oude[nox]>=2的点


最关键的是找出传递性和构造中间等效无关的状态,然后应用出入度进行构图求解


#include <vector>#include <list>#include <map>#include <set>#include <queue>#include <deque>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>#include<cstring>using namespace std;class PieOrDolphin {public:vector <int> Distribute(vector <int> choice1, vector <int> choice2) {int inde[60],oude[60];memset(inde,0,sizeof(inde));memset(oude,0,sizeof(oude));int m=choice1.size();vector<int>res(m,1);int i,s,t,tmp,u,v;for (i=0;i<m;i++){oude[choice1[i]]++;inde[choice2[i]]++;}while (1){s=-1;for (i=0;i<50;i++)if (abs(inde[i]-oude[i])>=2){s=i;break;}if (s==-1)break;if (inde[s]>oude[s]){for (i=0;i<m;i++)if (res[i]==1)res[i]=2;elseres[i]=1;for (i=0;i<50;i++){tmp=inde[i];inde[i]=oude[i];oude[i]=tmp;}}int que[1005],lq,rq;int fah[60],nofa[60];lq=rq=0;que[0]=s;memset(fah,-1,sizeof(fah));memset(nofa,-1,sizeof(nofa));t=-1;while (lq<=rq){int x=que[lq];if (inde[x]>oude[x]){t=x;break;}for (i=0;i<m;i++){if (res[i]==1){u=choice1[i];v=choice2[i];}else{u=choice2[i];v=choice1[i];}if (u==x && v!=s && fah[v]==-1){fah[v]=x;nofa[v]=i;que[++rq]=v;}}lq++;}if (t==-1)break;int lop=t;while (fah[lop]!=-1){if (res[nofa[lop]]==1)res[nofa[lop]]=2;elseres[nofa[lop]]=1;u=lop;v=fah[lop];inde[u]--;oude[u]++;inde[v]++;oude[v]--;lop=fah[lop];}}return (res);}};



0 0
原创粉丝点击