2019 Multi-University Training Contest 3 题解

1001-- deep sea big pineapple

Obviously such a small range of data we blind violence on the line. Then you can get out on the convex hull legal point right. Then I wa greedy, and found a counter-example, the feeling is dp, not dp, death

Dp actually very simple, we look at the range of enumeration break together end to end illegal to answer after you have updated on a regular interval dp.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef double db;
 4 const db eps=1e-10;
 5 int sign(db k){
 6     if (k>eps) return 1; else if (k<-eps) return -1; return 0;
 7 }
 8 int cmp(db k1,db k2){return sign(k1-k2);}
 9 int inmid(db k1,db k2,db k3){return sign(k1-k3)*sign(k2-k3)<=0;}
10 struct point{
11     db x,y;
12     point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
13     point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
14     point operator * (db k1) const{return (point){x*k1,y*k1};}
15     point operator / (db k1) const{return (point){x/k1,y/k1};}
16     int operator == (const point &k1) const{return cmp(x,k1.x)==0&&cmp(y,k1.y)==0;}
17     bool operator < (const point k1) const{
18         int a=cmp(x,k1.x);
19         if (a==-1) return 1; else if (a==1) return 0; else return cmp(y,k1.y)==-1;
20     }
21     db abs(){return sqrt(x*x+y*y);}
22     db abs2(){return x*x+y*y;}
23     db dis(point k1){return ((*this)-k1).abs();}
24 };
25 int inmid(point k1,point k2,point k3){return inmid(k1.x,k2.x,k3.x)&&inmid(k1.y,k2.y,k3.y);}
26 db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
27 db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y;}
28 point proj(point k1,point k2,point q){ // q 到直线 k1,k2 的投影
29     point k=k2-k1; return k1+k*(dot(q-k1,k)/k.abs2());
30 }
31 db disSP(point k1,point k2,point q){
32     point k3=proj(k1,k2,q);
33     if (inmid(k1,k2,k3)) return q.dis(k3); else return min(q.dis(k1),q.dis(k2));
34 }
35 vector<point> ConvexHull(vector<point>A,int flag=0){ // flag=0 不严格 flag=1 严格
36     int n=A.size(); vector<point>ans(n*2);
37     sort(A.begin(),A.end()); int now=-1;
38     for (int i=0;i<A.size();i++){
39         while (now>0&&sign(cross(ans[now]-ans[now-1],A[i]-ans[now-1]))<flag) now--;
40         ans[++now]=A[i];
41     } int pre=now;
42     for (int i=n-2;i>=0;i--){
43         while (now>pre&&sign(cross(ans[now]-ans[now-1],A[i]-ans[now-1]))<flag) now--;
44         ans[++now]=A[i];
45     } ans.resize(now); return ans;
46 }
47 int T,n,g;point o[105];db R;
48 int dp[404][404],b[404][404];
49 vector<point> v;point p;
50 bool can(point a,point b) {
51     for (int i = 0; i < g; i++){
52         if(cmp(disSP(a,b,o[i]),R)<=0)
53             return false;
54     }
55     return true;
56 }
57 int main(){
58     scanf("%d",&T);
59     while (T--){
60         v.clear();
61         memset(b,0, sizeof(b));
62         memset(dp,0, sizeof(dp));
63         scanf("%d%d%lf",&n,&g,&R);
64         for(int i=1;i<=n;i++){
65             scanf("%lf%lf",&p.x,&p.y);
66             v.push_back(p);
67         }
68         for(int i=0;i<g;i++){
69             scanf("%lf%lf",&o[i].x,&o[i].y);
70         }
71         v=ConvexHull(v);
72         int m = v.size();
73         for(int i=0;i<m-1;i++){
74             for(int j=i+2;j<m;j++){
75                 if(i==0&&j==m-1)continue;
76                 if(can(v[i],v[j])) {
77                     b[i][j]=b[j][i]=1;
78                 }
79             }
80         }
81         for(int len=3;len<=m;len++){
82             for(int i=0;i+len-1<m;i++){
83                 int ed = i+len-1;
84                 for(int j=i;j<=ed;j++){
85                     dp[i][ed]=max(dp[i][ed],dp[i][j]+dp[j][ed]);
86                 }
87                 dp[i][ed]+=b[i][ed];
88             }
89         }
90         printf("%d\n",dp[0][m-1]);
91     }
92 }
View Code

 

 

 

1012 - Yukikaze and Demons

Dominating Set on dag, increase the exchange of points of all the zero point of convergence, topology map built reverse order, if the point x is to be out ban, can not reach the sink, you will need all his father's lca x is out ban , it is determined which lca, which can be hung on lca below. So achievements.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1e5+5;
int T, n, m, indeg[maxn], par[maxn][20], depth[maxn];
vector<int>g[maxn], p[maxn];
queue<int>q;
void init(){
    memset(par,-1,sizeof(par));
    for(int i=1;i<=n+1;i++) g[i].clear(),p[i].clear(), indeg[i]=0;
}
int lca(int u, int v){
    if(depth[u]<depth[v]) swap(u,v);
    int t=depth[u]-depth[v];
    for(int i=0;i<=18;i++){
        if(t&(1<<i)) u=par[u][i];
    }
    if(u==v) return u;
    for(int i=18;i>=0 ; i-- ) {
         if (by [u] [i]! = By [v] [i]) = u by [u] [i], v = by [v] [i]; 
    } 
    Return by [the] [ 0 ]; 
} 
Void update ( int a, int ago) { 
    by [the] [ 0 ] = fa; track [u] = track [ago] + 1 ;
    for ( int i = 1 ; i <= 18 ; i ++ ) {
         if (by [u] [i- 1 ] == - 1 ) by [u] [i] = - 1 ;
        else by [u] [i] = by [by [u] [i- 1 ]] [i- 1];
    }
}
void topsort(){
    q.push(n);
    while(!q.empty()){
        int u=q.front(); q.pop();
        if(u!=n){
            int fa=p[u][0];
            for(int i=1;i<p[u].size();i++){
                fa=lca(fa,p[u][i]);
            }
            update(u,fa);
        }
        for(int i=0;i<g[u].size();i++){
            int v=g[u][i]; indeg[v]--;
            if(!indeg[v]) q.push(v);
        }
    }
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m); init(); int u, v;
        for(int i=1;i<=m;i++) scanf("%d%d",&u,&v), g[v].push_back(u), indeg[u]++, p[u].push_back(v);
        for(int i=1;i<=n;i++) if(!indeg[i]) g[n+1].push_back(i), p[i].push_back(n+1), indeg[i]++;
        n++; depth[n]=0;
        topsort();
        int q; scanf("%d",&q);
        while(q--){
            scanf("%d%d",&u,&v);
            printf("%d\n",depth[u]+depth[v]-depth[lca(u,v)]);
        }
    }
    return 0;
}
View Code

 

1011 - Squrirrel

$ Dp $. If you do not delete the edge, then the problem is a classic original title, now border erase, then, in fact, do not delete certain modifications and maintenance on the basis of the edge. We use the $ down [u] [0] $ and $ down [u] [1] $ node representing $ u $ to go to the sub-tree does not delete the longest side of the road and road border erase the longest, with $ up [ u] [0] $ and $ up [u] [1] $ represent the longest way to go to his father's correspondence. For $ down [u] [0] $, the transfer is clear, now consider $ down [u] [1] $, if you want to delete side, we will choose $ down [u] [0] $ corresponding tree subtree an edge, because in order to shorten the longest road, but we can not put up the road is the shortened as $ down [u] [1] $, because maybe go to the other sub-tree does not delete the longest side of the road longer than that, so we are seeking $ down [u] [0] $ time, requires not only the longest road, but also requires a time long way, and the two routes destined for different sub-tree, and finally $ down [ u] [1] $ is the longest path between a maximum value after passage length and the longest side views corresponding tree path deleted subtrees. $ Up [u] [0] $ and $ up [u] [1] $ method of seeking a little more complex, set $ f $ a $ U $ father, for $ up [u] [0] $, it is divided into two case, one is its first-$ f $, go down to $ f $ ancestry direction to go, the other is its first-$ f $, go down another $ f $ a sub-tree walk, the former When the process moves Clearly, the latter, then in front of the longest road maintenance and minor works long road again, not repeat them here. The $ up [u] [1] $, will be more complicated, for easier analysis, we wish to root for $ f $ and $ u $ delete sub-tree tree, so, in fact, is equivalent to the new tree request for $ f $ $ down [f] [0] $ and $ down [f] [1] $, $ f $ to finally add the right edge to the $ U $ (this deletion may select edges, but does not affect). It said earlier this need to maintain the maximum value and the second largest value, then it is easy to find, but what we can not really delete $ u $ corresponding sub-tree, so the $ u $ affect tree subtree we need to find ways to exclude Therefore, we wish to maintain the value of the top three if $ u $ tree subtree corresponding value in the previous three values, directly deleted, you can get the second largest value of the actual use of the maximum, and the other on as before, the code to see details.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<cstring>
 5 const int N=2e5+5;
 6 int down[N][2][2];
 7 int up[N][2];
 8 int T,n;
 9 typedef std::pair<int,int> P;
10 std::vector<P> g[N];
11 void init() {
12     for(int i=1;i<=n;i++) g[i].clear();
13 }
14 void dfs(int u,int fa) {
15     memset(down[u],0,sizeof(down[u]));
16     for(P c:g[u]) if(c.first!=fa){
17         int v=c.first;
18         dfs(v,u);
19         int L=down[v][0][0]+c.second;
20         if(L>down[u][0][0]) {
21             down[u][0][1]=down[u][0][0];
22             down[u][0][0]=L;
23         }
24         else if(L>down[u][0][1]) {
25             down[u][0][1]=L;
26         }
27     }
28     for(P c:g[u]) if(c.first!=fa) {
29         int v=c.first;
30         int L=down[v][0][0]+c.second,R=std::min(down[v][1][0]+c.second,down[v][0][0]);
31         if(L==down[u][0][0]) {
32             down[u][1][0]=std::max(R,down[u][0][1]);
33             break;
34         }
35     }
36     //printf("%d %d %d %d\n",u,down[u][0][0],down[u][0][1],down[u][1][0]);
37 }
38 void dfs2(int u,int fa) {
39     P s[3];
40     s[0]=P(up[u][0],up[u][1]);
41     s[1]=s[2]=P(0,0);
42     for(P c:g[u]) if(c.first!=fa) {
43         int v=c.first;
44         P t(down[v][0][0]+c.second,std::min(down[v][1][0]+c.second,down[v][0][0]));
45         if(t>s[0]) {
46             s[2]=s[1];
47             s[1]=s[0];
48             s[0]=t;
49         }
50         else if(t>s[1]) {
51             s[2]=s[1];
52             s[1]=t;
53         }
54         else if(t>s[2]) s[2]=t;
55     }
56     for(P c:g[u]) if(c.first!=fa) {
57         int v=c.first;
58         up[v][0]=up[u][0]+c.second;
59         int L=down[v][0][0]+c.second;
60         if(down[u][0][0]==L) up[v][0]=std::max(up[v][0],c.second+down[u][0][1]);
61         else up[v][0]=std::max(up[v][0],c.second+down[u][0][0]);
62         P t(down[v][0][0]+c.second,std::min(down[v][1][0]+c.second,down[v][0][0]));
63         int p=-1;
64         static int l,r;
65         for(int i=0;i<3;i++) if(t==s[i]) p=i;
66         up[v][1]=p?s[0].first:s[1].first;
67         l=p?0:1;
68         for(int i=0;i<3;i++) {
69             if(i==l||i==p) continue;
70             r=i;break;
71         }
72         up[v][1]=std::min(up[v][1],std::max(s[l].second,s[r].first)+c.second);
73         dfs2(v,u);
74     }
75     //printf("--%d %d %d\n",u,up[u][0],up[u][1]);
76 }
77 int main() {
78     scanf("%d",&T);
79     while(T--) {
80         scanf("%d",&n);
81         init();
82         for(int i=1,u,v,w;i<n;i++) {
83             scanf("%d%d%d",&u,&v,&w);
84             g[u].push_back(P(v,w));
85             g[v].push_back(P(u,w));
86         }
87         dfs(1,0);up[1][0]=up[1][1]=0;
88         dfs2(1,0);
89         int ans=1,val=std::min(std::max(down[1][0][0],up[1][1]),std::max(down[1][1][0],up[1][0]));
90         for(int i=2;i<=n;i++) {
91             int tmp=std::min(std::max(down[i][0][0],up[i][1]),std::max(down[i][1][0],up[i][0]));
92             if(tmp<val) ans=i,val=tmp;
93         }
94         printf("%d %d\n",ans,val);
95     }
96     return 0;
97 }
View Code

 

Guess you like

Origin www.cnblogs.com/Onlymyheart/p/11267401.html