码迷,mamicode.com
首页 > 其他好文 > 详细

[考试反思]图论专题测试:怀疑

时间:2020-01-26 17:45:02      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:str   min   opened   second   onclick   log   ++   随机数   define   

 没写完,但是好像有人需要代码,于是先发布出来。

回去之后记得贴排行榜。

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\n",ans);
26 }
View Code

 

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 }
View Code

 

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 }
View Code

 

[考试反思]图论专题测试:怀疑

标签:str   min   opened   second   onclick   log   ++   随机数   define   

原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12234343.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!