2019 summer on record

7.13 Day1 wfj fairy data structure seniors
 7.14 Day2 dp
 7.16 Day3 hankpipi (YZH) of graph theory
 7.17 Day4 mathematics


7.22 Day1 string associated burst zero ljq seniors
  T1 Median (Median)  
  that Italy: Given a length \ (n-\) arrangement, please meet all \ (1≤i≤j≤n \) and \ (j-i≡0 \ mod 2 \ ) number of \ ((I, J) \) , calculated by the first arrangement \ (I \) through \ (J \) a set of elements constituting the median \ (m [I: J] \) , and obtains the \ (m [i: j] * i * j \) and. \ (n \ leq 10 ^ {
4} \)   Solution: problem solution is doubly linked list seniors(Never learned)

#include <iostream>
#include <vector>
#include<cstdio>
using namespace std;
typedef long long int64;
int main() {
    freopen("median.in","r",stdin);
    freopen("median.out","w",stdout);
    int n; cin >> n;
    vector<int> element(n);
    for (int i = 0; i < n; i += 1) {
        cin >> element[i];
    }
    vector<pair<int, int>> neighbours(n + 1);
    int64 result = 0;
    for (int i = 0; i < n; i += 1) {
         //如果索引在[i,n]范围内,则该值有效 
        vector<bool> valid(n + 1, false);
        for (int j = i; j < n; j += 1) {
            valid[element[j]] = true;
        }
        valid[n + 1] = true;
        int last = 0;
        //值的数目>中间值,较低值的数目<=中间值
        //mid->中间值
        int bigger = (n - i), lower = 0, mid = 0;    
        //  计算每个值,左边和右边的下一个有效值 
        for (int j = 1; j <= n; j += 1) {
            if (not valid[j]) {
                continue;
            }
            if (bigger > lower) {
                mid = j;
                bigger -= 1;
                lower += 1;
            }
            // 最后一个元素将是当前元素左边的元素
            // 最后一个元素右边的元素将是这个元素
            neighbours[j].first = last;
            neighbours[last].second = j;
            last = j;
        }
        for (int j = n -1 ; j >= i; j -= 1) {
            if (lower == bigger + 1) {
                // this can be any formula, whatsoever
                result += (int64) (j + 1) * (i + 1) * mid;
            } 
            // 值位于擦除值的左侧和右侧
            int left = neighbours[element[j]].first;
            int right = neighbours[element[j]].second;
            // 从“列表”中删除此列表
            neighbours[left].second = right;
            neighbours[right].first = left;
            // 更新中间值、较大或较小的值。
            if (element[j] == mid) {
                bigger -= 1;
                mid = right;
            } else if (element[j] < mid) {
                lower -= 1;
            } else {
                bigger -= 1;
            }
            // even thou it requires only 1 iteration, the implementation
            // seems cleaner this way to put the median on the right spot
            // move the median to the left
            while (lower > bigger) {
                mid = neighbours[mid].first;
                bigger += 1;
                lower -= 1;
            }

            // move the median to the right
            while (bigger > lower) {
                mid = neighbours[mid].second;
                bigger -= 1;
                lower += 1;
            }
        }
    }

    cout << result << '\n';
    return 0;
}

Then yy myself out a writtenRun away faster than the standard int however burst on the examination room
Complexity \ (O (n ^ {2 }) \)

#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
int n;
int a[maxn],cnt[maxn];
long long ans;
inline void solve()
{
    int l=1,r=0,cntt=0,tmp;
    long long mid=0;
    for(int tl=1;tl<=n;++tl) 
    {
        for(int tr=tl;tr<=n;tr+=2)
        {
            while(l<tl)
            {
                if(a[l]<=mid) --cntt;//左端点显然只会递增
                --cnt[a[l++]];
            }
            while(r<tr)
            {
                if(a[++r]<=mid) ++cntt;
                ++cnt[a[r]];
            }
            while(r>tr)
            {
                if(a[r]<=mid) --cntt;
                --cnt[a[r--]];
            }
            tmp=((tr-tl)>>1)+1;
            if(tmp==1)
            {
                mid=a[tl];
                cntt=1;
                ans+=mid*tl*tr;
                continue;
            }
            while(cntt<tmp)
                cntt+=cnt[++mid];
            while(cntt>dizengtmp)
            {
                if(cntt-cnt[mid]<tmp) break;
                cntt-=cnt[mid--];
            }
            while(cntt==tmp)
            {
                if(cnt[mid]!=0) break;//处理mid为零的情况
                --mid;
            }
            ans+=mid*tl*tr;
        }
    }
}
int main()
{
    freopen("median.in","r",stdin);
    freopen("median.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d",&a[i]);
    solve();
    printf("%lld",ans);
    return 0;
}

T2 set (set)
  the meaning of problems: there is a \ (n-\) nodes of the tree, the root number \ (1 \) , there is initially an empty set on each node. Then performs a number of operations that are of the form: for all the nodes in the subtree rooted in this node, the increase in its corresponding set or delete elements \ (X \) . Each node of the operation must be carried out after all operations all of its ancestor node is complete. Already contains the elements of a \ (x \) is a collection of implementation of the enhanced elements \ (x \) operation, or does not contain the elements of a \ (x \) collection delete elements \ (x \) will not be the a collection of impact.
  Finally, ask each node corresponding to the size of the collection.
  Input format: The first line input comprises a positive integer \ (n-\) . The next \ (n-1 \) row each row two positive integers \ (U \) , \ (V \) , indicates the presence of a connected tree \ (u, v \) side two points. Thereafter \ (n-\) row, the first \ (I \) row of the first integer \ (k_ {i} \) , followed by \ (k_ {i} \) integer \ (x_ {j} \), Represents \ (I \) nodes corresponding to the operation. If \ (x_ {j} \) is positive, it indicates that adding elements \ (x_ {j} \) , if the \ (x {j} \) is negative, then it means an element \ (x_ {j} \) . Ensure \ (n-\ Leq ^ {10}. 5, \ FORALL X_ {I},. 1 \ Leq X_ {I} \ n-Leq \) , the same node is not more than twice the operation of any one element.
  Solution: Direct dfs, the way to maintain a collection of nodes, the recovery in the Retrospective
  complexity \ (O (n + n \ log n) \)

#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
struct Edge
{
    int fr,to;
}eg[maxn];
set<int> op[maxn],s;
set<int>::iterator it;
int edgenum,n,head[maxn],ans[maxn];
inline void add(int fr,int to)
{
    eg[++edgenum].fr=head[fr];
    eg[edgenum].to=to;
    head[fr]=edgenum;
}
inline void dfs(int now)
{
    int tmp;
    for(it=op[now].begin();it!=op[now].end();)
    {
        tmp=*it;
        ++it;
        if(tmp>0)
        {
            if(s.count(tmp)) op[now].erase(tmp);
            else s.insert(tmp);
        }
        else
        {
            if(!s.count(-tmp)) op[now].erase(tmp);
            else s.erase(-tmp);
        }
    }
    ans[now]=s.size();
    for(int i=head[now];i;i=eg[i].fr)
        dfs(eg[i].to);
    for(it=op[now].begin();it!=op[now].end();++it)
    {
        tmp=*it;
        if(tmp>0) s.erase(tmp);
        else s.insert(-tmp);
    }
}
int main()
{
    freopen("set.in","r",stdin);
    freopen("set.out","w",stdout);
    scanf("%d",&n);
    int u,v,k;
    for(int i=1;i<n;++i)
        scanf("%d%d",&u,&v),add(u,v);
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&k);
        for(int j=1;j<=k;++j)
            scanf("%d",&u),op[i].insert(u);
    }
    dfs(1);
    for(int i=1;i<=n;++i)
        printf("%d\n",ans[i]);
    return 0;
}

T3 StarCraft (craft)
  questions surface:
  As narrow highland battlefield can be considered a \ (r * c \) of grid array, each box may be unavailable through and through two cases.
  marine and zergling which always occupy a square through. Two zergling can be in the same square, but not at any one time marine and zergling not either died in the same box.
  have both marine life and zergling value (HP), the initial value of marine life \ (m \) , all values are zergling initial life \ (Z \) .
  Turn-based games can be abstracted as, in each round, marine first action. marine can choose to move in the vertical or horizontal direction of a cell, or each standing toward a gun zergling.marine situ zergling shot only (very narrow due Heights, marine can hit anywhere in the highlands will reduce the target zergling the value of life \ (1 \) point, when the value of life is reduced to a zergling \ (0 \)It will die when points or less. After completion of marine operations, all zergling not yet dead will also act only if a zergling and adjacent marine, marine attack it, otherwise it will be the shortest marine current position forward one space along their current position, if there are multiple Article shortest, zergling will press the left, on the right order, in order to try action (for example, if the left, are the shortest, zergling will go to the left). Note that if a path is not only zergling to the marine, then it does not move. If the two zergling simultaneously in the same cell marine, marine life value of only reduce \ (1 \) point , otherwise the attack will cause each zergling reduction in the value of marine life \ (1 \) points.
  At the end of a turn, if you believe all died zergling game victory, if marine life is reduced to the value of \ (0 \) points or less, or a game \ (T \) rounds but have not yet victory is considered a failure game . You need to determine whether the player may win, if possible, to obtain the output of the minimum number of rounds required for victory.
Input format: The first row r, c, t. Next, r c character lines each, "1" represents a non-through, "M" represents the initial position of the maring, "Z" and "z" represents the initial position of the two zergling. Finally a, b are of marine and zergling hp. Ensure \ (. 1 \ Leq m \ Leq 16 \) , \ (. 1 \ Leq Z \ Leq 99 \) , \ (. 1 \ Leq T \ Leq 50 \) , \ (. 1 \ R & lt Leq,.
  Solution: explosive found??? D seniors are not search
  complexity \ (O (R & lt * T * m. 3 ^ {^} * {C}. 3) \) , can pass.

#include<bits/stdc++.h>
using namespace std;
char mp[10][10];
int r,c,T,hp_m,hp_z,m,z1,z2;
int pos[40][40],wei[40][40],near[40][40];
int dx[4]={0,-1,0,1},dy[4]={-1,0,1,0};
int dp[55][40][40][40][18];
int go(int now,int d)//mergling的行动
{
    int i=(now-1)/c,j=(now-1)%c;
    int di=i+dx[d],dj=j+dy[d];
    if(di<0||dj<0||di>=r||dj>=c||mp[di][dj]=='1') return -1;
    return pos[di][dj];
}
int zgo(int now,int to)zergling的行动
{
    if(near[now][to]||!now) return now;
    int res=-1,dis=0x3f3f3f3f;
    for(int d=0;d<4;++d)
    {
        int tmp=go(now,d);
        if(tmp==-1) continue;
        if(wei[tmp][to]<dis) dis=wei[tmp][to],res=tmp;
    }
    if(dis>100) return now;
    return res;
}
inline void cmin(int& a,int b)
{
    a=a<b?a:b;
}
int main()
{
    freopen("craft.in","r",stdin);
    freopen("craft.out","w",stdout);
    scanf("%d%d%d",&r,&c,&T);
    for(int i=0;i<r;++i)
        scanf("%s",mp[i]);
    scanf("%d%d",&hp_m,&hp_z);
    m=z1=z2=-1;
    for(int i=0;i<r;++i)
        for(int j=0;j<c;++j)
        {
            pos[i][j]=i*c+j+1;
            if(mp[i][j]=='z'||mp[i][j]=='Z')
            {dierwei
                if(z1==-1) z1=pos[i][j];
                else z2=pos[i][j];
            }
            else if(mp[i][j]=='M') m=pos[i][j];
        }
    memset(wei,0x3f,sizeof(wei));
    for(int i=0;i<r;++i)//最短路
        for(int j=0;j<c;++j)
        {
            if(mp[i][j]=='1') continue;
            if(i&&mp[i-1][j]!='1') wei[pos[i][j]][pos[i-1][j]]=1;
            if(i!=r-1&&mp[i+1][j]!='1') wei[pos[i][j]][pos[i+1][j]]=1;
            if(j&&mp[i][j-1]!='1') wei[pos[i][j]][pos[i][j-1]]=1;T
            if(j!=c-1&&mp[i][j+1]!='1') wei[pos[i][j]][pos[i][j+1]]=1;
            wei[pos[i][j]][pos[i][j]]=0;
        }
    int size=r*c;
    for(int i=1;i<=size;++i)//判断两格相邻
        for(int d=0;d<4;++d)
            if(go(i,d)!=-1) near[i][go(i,d)]=1;
    for(int k=1;k<=size;++k)
        for(int i=1;i<=size;++i)
            for(int j=1;j<=size;++j)
                cmin(wei[i][j],wei[i][k]+wei[k][j]);
    memset(dp,0x3f,sizeof(dp));
    dp[0][m][z1][z2][hp_m]=dp[0][m][z2][z1][hp_m]=hp_z<<1;//第一维时间,第二维maring的行动,第三维一只zergling,第四位另一只,第五维是maring剩余的hp
    for(int t=0;t<T;++t)
        for(int tm=1;tm<=size;++tm)
            for(int tz1=0;tz1<=size;++tz1)
                for(int tz2=0;tz2<=size;++tz2)
                    for(int thp=1;thp<=hp_m;++thp)
                    {
                        int hp_now=dp[t][tm][tz1][tz2][thp];
                        if(hp_now>100) continue;
                        for(int d=0;d<4;++d)
                        {
                            int nm=go(tm,d);
                            if(nm==-1||nm==tz1||nm==tz2) continue;
                            int v=0;
                            int nz1=zgo(tz1,nm),nz2=zgo(tz2,nm);
                            if(near[tz1][nm]) ++v;
                            if(near[tz2][nm]&&tz1!=tz2&&hp_now>hp_z) ++v;
                            if(thp>v) cmin(dp[t+1][nm][nz1][nz2][thp-v],hp_now);
                        }
                        int nz1=zgo(tz1,tm),nz2=zgo(tz2,tm);
                        if(hp_now==1)
                        {
                            printf("WIN\n%d\n",t+1);
                            return 0;
                        }
                        int v=0;
                        if(near[tz1][tm]) ++v;
                        if(near[tz2][tm]&&tz1!=tz2&&hp_now-1>hp_z) ++v;
                        if(thp>v)
                        {
                            if(hp_now-1>hp_z) cmin(dp[t+1][tm][nz1][nz2][thp-v],hp_now-1);
                            else cmin(dp[t+1][tm][nz1][0][thp-v],hp_now-1);
                        }
                    }
    puts("LOSE");
    return 0;
}

T4 Star (Stars)
  segment tree title template scanning line (the boundary of the window star counted)
  complexity \ (O (n \ log n ) \)

#include<bits/stdc++.h>
using namespace std;
int x[100005];
struct Line
{
    int l,r,h,val;
    friend bool operator < (Line a,Line b)
        {
            if(a.h==b.h) return a.val>b.val;
            return a.h<b.h;
        }
}li[100005];
struct SegTree
{
    int l,r,val,lazy;
}node[400005];
inline void pushup(int rt)
{
    node[rt].val=max(node[rt<<1].val,node[rt<<1|1].val);
}
inline void pushdown(int rt)
{
    if(node[rt].lazy)
    {
        node[rt<<1].lazy+=node[rt].lazy;
        node[rt<<1|1].lazy+=node[rt].lazy;
        node[rt<<1].val+=node[rt].lazy;
        node[rt<<1|1].val+=node[rt].lazy;
        node[rt].lazy=0;
    }
}
inline void build(int rt,int l,int r)
{
    node[rt].l=l,node[rt].r=r;
    node[rt].val=node[rt].lazy=0;
    if(l==r) return;
    int mid=(l+r)>>1;
    build(rt<<1,l,mid);
    build(rt<<1|1,mid+1,r);
}
inline void update(int rt,int fr,int to,int l,int r,int val)
{
    if(fr<=l&&to>=r)
    {
        node[rt].val+=val;
        node[rt].lazy+=val;
        return;
    }
    pushdown(rt);
    int mid=(l+r)>>1;
    if(fr<=mid) update(rt<<1,fr,to,l,mid,val);
    if(to>mid) update(rt<<1|1,fr,to,mid+1,r,val);
    pushup(rt);
}
inline int query(int rt,int fr,int to,int l,int r)
{
    if(fr<=l&&to>=r)
        return node[rt].val;
    pushdown(rt);
    int mid=(l+r)>>1,ans=0;
    if(fr<=mid) ans=query(rt<<1,fr,to,l,mid);
    if(to>mid) ans=max(ans,query(rt<<1|1,fr,to,mid+1,r));
    return ans;
}
int cnt;
int main()
{
    freopen("stars.in","r",stdin);
    freopen("stars.out","w",stdout);
    int t,n,W,H,xx,y,z;
    //scanf("%d",&t);
    //while(t--)
    //{
        scanf("%d%d%d",&n,&W,&H);
        cnt=0;
        for(int i=1;i<=n;++i)
        {
            scanf("%d%d%d",&xx,&y,&z);
            li[++cnt].l=xx,li[cnt].r=xx+W,li[cnt].h=y,li[cnt].val=z,x[cnt]=xx;
            li[++cnt].l=xx,li[cnt].r=xx+W,li[cnt].h=y+H,li[cnt].val=-z,x[cnt]=xx+W;
        }
        sort(li+1,li+cnt+1);
        sort(x+1,x+cnt+1);
        build(1,1,cnt);
        int maxx=-0x3f3f3f3f,tx=unique(x+1,x+cnt+1)-x-1;
        for(int i=1;i<=cnt;++i)
        {
            li[i].l=lower_bound(x+1,x+tx+1,li[i].l)-x;
            li[i].r=lower_bound(x+1,x+tx+1,li[i].r)-x;
            update(1,li[i].l,li[i].r,1,cnt,li[i].val);
            maxx=max(maxx,node[1].val);
        }
        printf("%d\n",maxx);
        //}
    return 0;
}

7.23 Day2 burst number zero strange thing received
at T1 count
  that Italy: given a \ (n-\) points, \ (m \) without edges to FIG. From the definition of a (I \) \ point \ (J \) the cost of the path points is the maximum of all edge sides on the right path. \ (i \) to \ (j \) the cost is defined as the minimum cost of all of the i to j path.
  I asked how many of \ (1≤i <j≤n \) satisfies \ (i \) to \ (j \) cost exactly \ (the X-\) . Ensure \ (n-\ Leq 10 ^ {. 5} \) , \ (m \ Leq. 3 * 10 ^ {. 5} \) , \ (X \ Leq 10 ^ {. 9} \)
  Solution: converted to less \ (X \) minus less than \ (x \) logarithm. Statistical dfs then directly re-request blocks Unicom \ (C_ {n} ^ { 2} \) look like a
  complexity \ (O (n) \)

#include<bits/stdc++.h>
using namespace std;
#define maxn 300005
struct Edge
{
    int fr,to,val;
}eg[maxn<<1];
int edgenum,cnt,vis[maxn],head[maxn],fr[maxn],to[maxn],val[maxn];
long long num[maxn];
inline void add(int fr,int to,int val)
{
    eg[++edgenum].fr=head[fr];
    eg[edgenum].to=to;
    eg[edgenum].val=val;
    head[fr]=edgenum;
}
inline void dfs(int rt)
{
    vis[rt]=1;
    for(int i=head[rt];i;i=eg[i].fr)
    {
        if(vis[eg[i].to]) continue;
        vis[eg[i].to]=1;
        ++num[cnt];
        dfs(eg[i].to);
    }
}
int main()
{
    freopen("xdis.in","r",stdin);
    freopen("xdis.out","w",stdout);
    int n,m,x;
    long long ans=0;
    scanf("%d%d%d",&n,&m,&x);
    for(int i=1;i<=m;++i)
        scanf("%d%d%d",&fr[i],&to[i],&val[i]);
    for(int i=1;i<=m;++i)
        if(val[i]<=x) add(fr[i],to[i],val[i]),add(to[i],fr[i],val[i]);
    for(int i=1;i<=n;++i)
        if(!vis[i])
        {
            ++num[++cnt];
            dfs(i);
        }
    for(int i=1;i<=cnt;++i)
        ans+=(num[i]-1)*(num[i])/2;
    for(int i=1;i<=edgenum;++i)
        eg[i].fr=eg[i].to=eg[i].val=0;
    cnt=edgenum=0;
    memset(head,0,sizeof(head));
    memset(num,0,sizeof(num));
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=m;++i)
        if(val[i]<x) add(fr[i],to[i],val[i]),add(to[i],fr[i],val[i]);
    for(int i=1;i<=n;++i)
        if(!vis[i])
        {
            ++num[++cnt];
            dfs(i);
        }
    for(int i=1;i<=cnt;++i)
        ans-=(num[i]-1)*(num[i])/2;
    printf("%lld\n",ans);
    return 0;
}

T2 problem tree (tree)
  questions surface: there is one by the \ (n \) unrooted tree points constituted, this \ (n \) points respectively as the root node, we can create \ (n \) trees rooted tree. There \ (q \) th inquiry, asking each given two points \ (a \) and \ (b \) , we want to know that \ (n \) a rooted tree, how many trees meet \ (a \) is \ (B \) of ancestors or \ (B \) is \ (a \) of ancestors. Ensure \ (n-, Q \ Leq * 2 ^ {10}. 5 \) .
  Solution: First, to seek out again dfs size at each node in the case where a root. If the two are not lca any two nodes of a, then the direct addition size(I just put the launch in the examination room, the rest of pushing the wrong)
  In other cases, set \ (x, Y \) is interrogated two nodes x and deeper. We want to find x to y y next piece of chain meaning son , is set to z. The answer equals \ (n--size [Z] + size [X] \) . Since the \ (Z \) above and \ (X \) below (including x) clearly meet the requirements of all the points.
  Complexity \ (O (n \ log n ) \)

#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
int n,q;
struct Edge
{
    int fr,to;
}eg[maxn<<1];
int head[maxn],edgenum;
int top[maxn],size[maxn],son[maxn],id[maxn],fa[maxn],deep[maxn];
inline void add(int fr,int to)
{
    eg[++edgenum].fr=head[fr];
    eg[edgenum].to=to;
    head[fr]=edgenum;
}
inline int lca(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        x=fa[top[x]];
    }
    if(deep[x]>deep[y]) swap(x,y);
    return x;
}
inline int llca(int x,int y)
{
    int last;
    if(deep[x]>deep[y]) swap(x,y);
    while(top[x]!=top[y]) last=y,y=fa[top[y]];
    if(x!=y) return son[x];
    return top[last];
}
inline int getans(int x,int y)
{
    int tmp=lca(x,y);
    if(tmp!=x&&tmp!=y) return size[x]+size[y];
    if(tmp==x) return n-size[llca(x,y)]+size[y];
    return n-size[llca(x,y)]+size[x]; 
}
inline void dfs1(int rt,int fat,int dep)
{
    size[rt]=1;
    fa[rt]=fat;
    deep[rt]=dep;
    int tmp,maxson=-1;
    for(int i=head[rt];i;i=eg[i].fr)
    {
        tmp=eg[i].to;
        if(tmp==fat) continue;
        dfs1(tmp,rt,dep+1);
        size[rt]+=size[tmp];
        if(size[tmp]>maxson)
            maxson=size[tmp],son[rt]=tmp;
    }
}
int cnt;
inline void dfs2(int rt,int topp)
{mindis(s1,t1)≤l1&&mindis(s2,t2)≤l2
    id[rt]=++cnt;
    top[rt]=topp;
    if(!son[rt]) return;
    dfs2(son[rt],topp);
    for(int i=head[rt];i;i=eg[i].fr)
        if(eg[i].to!=fa[rt]&&eg[i].to!=son[rt])
            dfs2(eg[i].to,eg[i].to);
}
int main()
{
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    scanf("%d%d",&n,&q);
    int u,v;
    for(int i=1;i<n;++i)
    {
        scanf("%d%d",&u,&v);
        add(u,v),add(v,u);
    }
    dfs1(1,0,1);
    dfs2(1,1);
    for(int i=1;i<=q;++i)
    {
        scanf("%d%d",&u,&v);
        printf("%d\n",getans(u,v));
    }
    return 0;
}

T3 event (Party)
  that Italy: given \ (n-\) point \ (m \) side connected undirected graph, edge weight of the edge of a given \ (s1, t1, l1, s1, t2, l2 \ ) , in seeking to meet the \ (mindis (s1, t1) \ leq l1 \ & \ & mindis (s2, t2) \ leq l2 \) up to the number of sides in the broken condition. Ensure \ (n, m \ leq 3000
\)   Solution: conversion requires a minimum of how many sides. If the two do not overlap the shortest path, directly adding two lengths. Otherwise enumeration intersection \ (i, J \) , to update the minimum number of edges. As the number of sides so rarely used spfa. (This question is the ratio of 3-fold slower dijskra SPFA)
  complexity \ (O (n ^ {2 }) \)

#include<bits/stdc++.h>
using namespace std;
#define maxn 3005
#define mp make_pair
#define pa pair<int,int>
struct Edge
{
    int fr,to,val;
}eg[maxn<<1];
int head[maxn],edgenum,n,m,dis[maxn][maxn],vis[maxn];
int s1,t1,l1,s2,t2,l2;
inline void add(int fr,int to)
{
    eg[++edgenum].fr=head[fr];
    eg[edgenum].to=to;
    eg[edgenum].val=1;
    head[fr]=edgenum;
}
inline void spfa(int st)
{
    queue<int> q;
    memset(vis,0,sizeof(vis));
    q.push(st);
    dis[st][st]=0;
    vis[st]=1;
    int tmp;
    while(!q.empty())
    {
        tmp=q.front();
        q.pop();
        vis[tmp]=0;
        for(int i=head[tmp];i;i=eg[i].fr)
        {
            if(dis[st][eg[i].to]>dis[st][tmp]+eg[i].val)
            {
                dis[st][eg[i].to]=dis[st][tmp]+eg[i].val;
                if(!vis[eg[i].to])
                {
                    vis[eg[i].to]=1;
                    q.push(eg[i].to);
                }
            }
        }
    }
}
inline void cmin(int& a,int b)
{
    a=min(a,b);
}
int main()
{
    freopen("party.in","r",stdin);
    freopen("party.out","w",stdout);
    scanf("%d%d",&n,&m);
    int u,v;
    for(int i=1;i<=m;++i)
    {
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    scanf("%d%d%d%d%d%d",&s1,&t1,&l1,&s2,&t2,&l2);
    memset(dis,0x3f,sizeof(dis));
    for(int i=1;i<=n;++i)
        spfa(i);
    if(dis[s1][t1]>l1||dis[s2][t2]>l2)
    {
        puts("That's all trouble!");
        return 0;
    }
    int ans=dis[s1][t1]+dis[s2][t2];
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
        {
            if(dis[s1][i]+dis[i][j]+dis[j][t1]<=l1&&dis[s2][i]+dis[i][j]+dis[j][t2]<=l2)
                cmin(ans,dis[s1][i]+dis[s2][i]+dis[i][j]+dis[j][t1]+dis[j][t2]);
            if(dis[s1][j]+dis[j][i]+dis[i][t1]<=l1&&dis[s2][i]+dis[i][j]+dis[j][t2]<=l2)
                cmin(ans,dis[s1][j]+dis[j][i]+dis[i][t1]+dis[s2][i]+dis[j][t2]);
        }
    printf("%d\n",m-ans);
    return 0;
}

T4 minimum spanning tree (Graph) 
 that Italy: \ (n-\) points, \ (m \) operations, \ (ab & the Add \) represents the \ (a, b \) between the right side is connected to a current operation number side, \ (the delete K \) shows a right side in FIG largest \ (K \) edges delete, \ (the Return \) represents the withdrawal of the last operation. Right side is obtained after each operation and the current minimum spanning tree.
  Minimum spanning tree does not exist, the output 0. The first is not guaranteed \ (the Return \) , \ (the Return \) not preceded by \ (the Return \) , the current number of edges in FIG greater than or equal K, \ (n-\ Leq. 3. 5 * 10 ^ {}, m \ Leq. 5 5 * 10 ^ {} \) .
  answer:Persistable lct
Seniors solution to a problem directly Kuai (Because I will not.): Cures data structure silly school students
section points with the official explanations See: Interpretations
This question is a relatively strong nature: the right side is increasing; deleted are the last to join the side; only return back to the previous version.
Without these properties may need to be persistent dynamic tree? but since nature so strong, perhaps solution is relatively simple.
since the incremental side right, one side will be staying on until the minimum spanning tree is removed.
because of all deleted the maximum side edge weights, do not worry there will be deleted after a particular edge into the other side of the minimum spanning tree.
In order to support border erase operation can be used according to rank merge disjoint-set, because top-down border erase, the sub-tree size also can be easily maintained.
The only trouble spot is to cancel the operation, can be resolved in a clever way .
this problem is not by force, so when each operation can know what the next operation type.

  • If it is then withdrawn plus side, you can simulate this process, the complexity is not affected.
    If the edge is deleted and then revoked, it is not necessary to remove these edges, has not joined directly answer these output side (that means record the answer every time)
    some of the details of the place to note that, after such deletion \ (k \) edges than the \ (k \) strip into the side of the spanning tree.

Code? First the goo


  • 7.25 Day3 burst zero lst sister school of some (fog) of the weird things that do not give negative feedback large sample continuously Tham D Festival
  • 7.26 Day4 burst zero mathematical gods do not give a large sample Poor immortal question a topic Jiechai comment

Guess you like

Origin www.cnblogs.com/123789456ye/p/11299247.html