[考试反思]图论专题测试:怀疑
Posted hzoi-deepinc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[考试反思]图论专题测试:怀疑相关的知识,希望对你有一定的参考价值。
没写完,但是好像有人需要代码,于是先发布出来。
回去之后记得贴排行榜。
0+0+55.rk11.
考场上想出了T1的三分,不确定,没有写。
写了另一个好像靠谱点的二分,但是好像写挂了。。。
T2没读题,又是没读题,又是没读题!!!!
没看到它要求的是简单路径,于是简单爆9.
T3一眼网络流,两眼不会流,三眼状压写完就走。
最后也就T3有分。靠着一个状压苟到这个名次。。?
T1:center
题目大意:选择图上(点或边)上任意一点,使所有节点到这个节点最远的距离最小。$ n le 200$
这是一堆一次函数在取max啊,显然是单谷的。
预处理出来点对距离,然后枚举每条边在边上三分最优位置更新答案。
但是为什么会卡参啊?0.4-0.6就过不去0.3-0.7就行,求解???
1 #include<bits/stdc++.h> 2 using namespace std; 3 priority_queue<pair<int,int>>q; 4 int dt[512][512],n,m,fir[512],l[543210],to[543210],v[543210],ec=1;double ans=1e9; 5 void link(int a,int b,int w){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;v[ec]=w;} 6 double cal(int e,double p){ 7 e<<=1;double d=0; 8 for(int i=1;i<=n;++i)d=max(d,min(dt[to[e]][i]+p,dt[to[e|1]][i]+v[e]-p)); 9 return d; 10 } 11 int main(){ 12 scanf("%d%d",&n,&m); 13 for(int i=1,a,b,w;i<=m;++i)scanf("%d%d%d",&a,&b,&w),link(a,b,w),link(b,a,w); 14 for(int s=1;s<=n;++s){ 15 for(int t=1;t<=n;++t)dt[s][t]=1000000000;dt[s][s]=0;q.push(make_pair(0,s)); 16 while(!q.empty()){ 17 int p=q.top().second,d=-q.top().first;q.pop();if(d!=dt[s][p])continue; 18 for(int i=fir[p];i;i=l[i])if(dt[s][to[i]]>d+v[i])q.push(make_pair(-(dt[s][to[i]]=d+v[i]),to[i])); 19 } 20 } 21 for(int i=1;i<=m;++i){ 22 double l=0,r=v[i<<1]; 23 while(r-l>1e-5)if(cal(i,l*0.3+r*0.7)<cal(i,l*0.7+r*0.3))l=l*0.7+r*0.3;else r=l*0.3+r*0.7; 24 ans=min(ans,cal(i,l)); 25 }printf("%.2lf ",ans); 26 }
T2:escape
题目大意:给定无向图,求严格次短简单路径且满足所有最短路上的边必须按照原方向经过。$n le 100000,m le 500000,w le 1000$
次短路可以分成三部分,先从1号点沿着最短路走到A,然后再从A走非最短路走到B,在从B走最短路到n。
暴力的做法时枚举AB。复杂度不可接受。
二进制分组分为A组B组就可以做了。
细节很多,注意1到A和B到n两部分都必须沿着最短路边定向走不然的话会导致出现非简单路径。
例子:4 4 1 2 1 2 3 1 1 3 1 1 4 666
然后中间一定要走非最短路,双向都不能走,不然也会导致形成非简单路径。
在这种前提下,你走出的当然不是最短路,而又是简单路径,在考虑到所有点对后就会找到次短路。
不要忘了在二进制分组时1为A0为B以及0为A1为B的两种情况都要考虑。
然而这貌似不是正解,题解里只给了这种做法,好像比正解多了一个log导致过不去,而且常数也小不了。实测有且只有70分。
在随机数据下A和B的随机某一位不同的概率为$50%$。所以我们不必都做完,只对最低的6位做然后更新答案正确率就达到$99\%$左右了,可以AC。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define S 1000005 4 int n,m,fir[S],l[S],to[S],w[S],ec=1,nt[S],dt[S],dp[S],al[S],D[S],ans=1234567890,Fir[S],L[S],To[S],W[S],Ec=1; 5 priority_queue<pair<int,int>>q; 6 void link(int a,int b,int v){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;w[ec]=v;} 7 void Link(int a,int b,int v){if(v>ans)return;L[++Ec]=Fir[a];Fir[a]=Ec;To[Ec]=b;W[Ec]=v;} 8 void sch(int p){ 9 if(al[p])return;al[p]=1; 10 for(int i=fir[p];i;i=l[i])if(dt[to[i]]==dt[p]-w[i])nt[i^1]=2,nt[i]=1,sch(to[i]); 11 } 12 int main(){ 13 scanf("%d%d",&n,&m); 14 for(int i=1,x,y,v;i<=m;++i)scanf("%d%d%d",&x,&y,&v),link(x,y,v),link(y,x,v); 15 for(int i=1;i<=n;++i)dt[i]=dp[i]=1234567890; 16 q.push(make_pair(dt[1]=0,1)); 17 while(!q.empty()){ 18 int p=q.top().second,d=-q.top().first;q.pop(); 19 if(d!=dt[p])continue; 20 for(int i=fir[p];i;i=l[i])if(dt[to[i]]>d+w[i])q.push(make_pair(-(dt[to[i]]=d+w[i]),to[i])); 21 }sch(n); 22 for(int i=1;i<=n;++i)dt[i]=1234567890;q.push(make_pair(dt[1]=0,1)); 23 while(!q.empty()){ 24 int p=q.top().second,d=-q.top().first;q.pop(); 25 if(d!=dt[p])continue; 26 for(int i=fir[p];i;i=l[i])if(dt[to[i]]>d+w[i]&&nt[i]==2)q.push(make_pair(-(dt[to[i]]=d+w[i]),to[i])); 27 }q.push(make_pair(dp[n]=0,n)); 28 while(!q.empty()){ 29 int p=q.top().second,d=-q.top().first;q.pop(); 30 if(d!=dp[p])continue; 31 for(int i=fir[p];i;i=l[i])if(dp[to[i]]>d+w[i]&&nt[i]==1)q.push(make_pair(-(dp[to[i]]=d+w[i]),to[i])); 32 }srand(time(0)); 33 for(int b=0;b<=5;b++){int x=0; 34 X: for(int i=0;i<=n+1;++i)Fir[i]=0,D[i]=1234567890;Ec=1; 35 for(int i=1;i<=n;++i)if((i&1<<b)!=0^x)Link(0,i,dt[i]);else Link(i,n+1,dp[i]); 36 for(int i=2;i<=ec;i++)if(!nt[i])Link(to[i],to[i^1],w[i]); 37 q.push(make_pair(D[0]=0,0)); 38 while(!q.empty()){ 39 int p=q.top().second,d=-q.top().first;q.pop(); 40 if(d!=D[p])continue; 41 for(int i=Fir[p];i;i=L[i])if(D[To[i]]>d+W[i])q.push(make_pair(-(D[To[i]]=d+W[i]),To[i])); 42 }ans=min(ans,D[n+1]); 43 if(!x){x=1;goto X;} 44 }cout<<(ans==1234567890?-1:ans)<<endl; 45 }
T3:chip
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define T (n<<1|1) 4 #define N 666666 5 #define inf 998244353 6 int n,a,b,pc,l[N],to[N],fir[88],ans=9999,ec,v[N],w[N],q[N],d[N],al[88],iq[88],fee,lc[66],rc[66],tot;char s[44][44]; 7 void link(int a,int b,int V,int W){ 8 l[++ec]=fir[a];fir[a]=ec;to[ec]=b;v[ec]=V;w[ec]=+W; 9 l[++ec]=fir[b];fir[b]=ec;to[ec]=a;v[ec]=0;w[ec]=-W; 10 } 11 bool SPFA(){ 12 for(int i=1;i<=T;++i)d[i]=inf,al[i]=0; 13 for(int h=1,t=1;h<=t;iq[q[h]]=0,++h)for(int i=fir[q[h]];i;i=l[i])if(d[to[i]]>d[q[h]]+w[i]&&v[i]){ 14 if(!iq[to[i]])q[++t]=to[i],iq[to[i]]=1; 15 d[to[i]]=d[q[h]]+w[i]; 16 }return d[T]!=inf; 17 } 18 int dfs(int p,int flow){ 19 if(p==T)return flow; 20 int r=flow;al[p]=1; 21 for(int i=fir[p];i&&r;i=l[i])if(!al[to[i]]&&d[to[i]]==d[p]+w[i]&&v[i]){ 22 int x=dfs(to[i],min(v[i],r)); 23 if(!x)d[to[i]]=inf; 24 v[i]-=x;v[i^1]+=x;r-=x;fee+=x*w[i]; 25 }return flow-r; 26 } 27 int main(){ 28 scanf("%d%d%d",&n,&a,&b); 29 for(int i=1;i<=n;++i)scanf("%s",s[i]+1); 30 for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(s[i][j]!=‘/‘)lc[i]++,rc[j]++,tot++,pc+=s[i][j]==‘C‘; 31 for(int x=0;x<=n;++x){ 32 ec=1;for(int i=0;i<=T;++i)fir[i]=0; 33 for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)if(s[i][j]==‘.‘)link(i,j+n,1,1); 34 for(int i=1;i<=n;++i)link(0,i,lc[i],0),link(i+n,T,rc[i],0),link(i,i+n,x,0); 35 int fl=0;fee=0; 36 while(SPFA())fl+=dfs(0,inf); 37 if(x*b<=(fl-fee)*a&&fl==tot)ans=min(ans,fee); 38 }if(ans==9999)puts("impossible");else cout<<tot-pc-ans<<endl; 39 }
以上是关于[考试反思]图论专题测试:怀疑的主要内容,如果未能解决你的问题,请参考以下文章