zoukankan      html  css  js  c++  java
  • BZOJ[1969] [Ahoi2005]LANE 航线规划

    这个题很清真

    就是可以考虑将删除的边倒叙插入,因为题面中说了,保证删了所有边之后,保证图的连通性 ,所以先在删完点的图上缩点,然后剩下的边就是关键边,之后再把删除的边插入,这样就会使得之前的一些点之间的关键边的不关键,之后用线段树维护就行了

      1 #include <set>
      2 #include <cmath>
      3 #include <cstdio>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <iostream>
      7 #include <algorithm>
      8 # define maxM 100010
      9 # define maxn 30010
     10 # define MP make_pair
     11 # define X first
     12 # define Y second
     13 using namespace std;
     14 void ot(){cout<<"***"<<endl;}
     15 void fen(){cout<<"-------------"<<endl;}
     16 typedef pair<int,int> Pi;
     17 int n,m;
     18 struct LINK{    
     19     struct node{
     20         int u,v,nxt;
     21     }g[2*maxM];
     22     int adj[maxn],e;
     23     void add(int u,int v){
     24         g[e]=(node){u,v,adj[u]};
     25         adj[u]=e++;
     26     }
     27     LINK(){memset(adj,-1,sizeof(adj)); e=0;}
     28 }A,B;
     29 Pi bi[maxM];
     30 bool cmp(const Pi a,const Pi b){
     31     if(a.X==b.X) return a.Y<b.Y;
     32     return a.X<b.X;
     33 }
     34 struct QQ{
     35     int od,u,v,ans;
     36 }Q[maxM];
     37 int tip;
     38 void init(){
     39     scanf("%d%d",&n,&m);
     40     for(int i=1;i<=m;i++){
     41         scanf("%d%d",&bi[i].X,&bi[i].Y);
     42         if(bi[i].X>bi[i].Y) swap(bi[i].X,bi[i].Y);
     43 //        cout<<bi[i].X<<"  "<<bi[i].Y<<endl;
     44     }
     45 //    ot(); exit(0);
     46     sort(bi+1,bi+m+1,cmp);
     47     int x,y,z;
     48     while(1){
     49         scanf("%d",&x); if(x==-1) break;
     50         Q[++tip].od=x;  scanf("%d%d",&Q[tip].u,&Q[tip].v);
     51         if(Q[tip].u>Q[tip].v) swap(Q[tip].u,Q[tip].v);
     52 //        cout<<"x=="<<x<<"  "<<Q[tip].u<<"  "<<Q[tip].v<<endl;
     53     }
     54 }
     55 bool operator < (const Pi a,const Pi b){
     56     if(a.X==b.X) return a.Y<b.Y;
     57     return a.X<b.X;
     58 }
     59 bool pd[maxM];
     60 void Del_lk(){
     61     int pos;
     62     for(int i=1;i<=tip;i++){
     63         if(Q[i].od) continue;
     64         pos=lower_bound(bi+1,bi+m+1,MP(Q[i].u,Q[i].v) )-bi;
     65         pd[pos]=1;
     66     }
     67     for(int i=1;i<=m;i++){
     68         if(pd[i]) continue;
     69         A.add(bi[i].X,bi[i].Y); A.add(bi[i].Y,bi[i].X);
     70     }
     71 }
     72 int dfn[maxn],low[maxn],stack[maxn],belong[maxn],cnt,stp,head;
     73 bool instack[maxn];
     74 void tarjan(int x,int fa){
     75     dfn[x]=low[x]=++stp; stack[++head]=x; instack[x]=1;
     76     for(int i=A.adj[x];i!=-1;i=A.g[i].nxt){
     77         int v=A.g[i].v; if(v==fa) continue;
     78         if(dfn[v]==-1){
     79             tarjan(v,x); low[x]=min(low[x],low[v]);
     80         }
     81         else if(instack[v]) low[x]=min(low[x],dfn[v]);
     82     }
     83     if(low[x]==dfn[x]){
     84         int tmp; cnt++;
     85         while(1){
     86             tmp=stack[head--];
     87             instack[tmp]=0;
     88             belong[tmp]=cnt;
     89             if(x==tmp) break;
     90         }
     91     }
     92 }
     93 int fa[maxn],dep[maxn],size[maxn],son[maxn];
     94 void dfs1(int x){
     95     size[x]=1;
     96     for(int i=B.adj[x];i!=-1;i=B.g[i].nxt){
     97         int v=B.g[i].v; if(v==fa[x]) continue;
     98         dep[v]=dep[x]+1; fa[v]=x; 
     99         dfs1(v);
    100         size[x]+=size[v];
    101         if(size[son[x]] < size[v]) son[x]=v;
    102     }
    103 }
    104 int top[maxn],id[maxn],Pos[maxn];
    105 void dfs2(int x,int tp){
    106     top[x]=tp; Pos[x]=++stp; id[stp]=x; 
    107     if(son[x]) dfs2(son[x],tp);
    108     for(int i=B.adj[x];i!=-1;i=B.g[i].nxt){
    109         int v=B.g[i].v; if(v==fa[x] || v==son[x]) continue;
    110         dfs2(v,v);
    111     }
    112 }
    113 int sum[4*maxn],mk[4*maxn];
    114 void pushup(int now){
    115     sum[now]=sum[now<<1]+sum[now<<1|1];
    116 }
    117 void pushdown(int now,int l,int r,int mid){
    118     if(mk[now]==-1) return;
    119     int ls=now<<1,rs=now<<1|1;
    120     sum[ls]=mk[now]*(mid-l+1); mk[ls]=mk[now];
    121     sum[rs]=mk[now]*(r-mid); mk[rs]=mk[now];
    122     mk[now]=-1;
    123 }
    124 void upd(int left,int right,int now,int l,int r,int num){
    125     if(left<=l && r<=right){
    126         sum[now]=num*(r-l+1); mk[now]=num; return;
    127     }
    128     int mid=(l+r)>>1;
    129     pushdown(now,l,r,mid);
    130     if(left<=mid) upd(left,right,now<<1,l,mid,num);
    131     if(right>mid) upd(left,right,now<<1|1,mid+1,r,num);
    132     pushup(now);
    133 }
    134 int query(int left,int right,int now,int l,int r){
    135     if(left<=l && r<=right) return sum[now];
    136     int mid=(l+r)>>1;
    137     pushdown(now,l,r,mid);
    138     int ret=0;
    139     if(left<=mid) ret+=query(left,right,now<<1,l,mid);
    140     if(right>mid) ret+=query(left,right,now<<1|1,mid+1,r);
    141     return ret;
    142 }
    143 void change(int x,int y){
    144     int tx=top[x],ty=top[y];
    145     int ret=0;
    146     while(tx^ty){
    147         if(dep[tx]<dep[ty]) swap(tx,ty),swap(x,y);
    148         upd(Pos[tx],Pos[x],1,1,stp,0);
    149         x=fa[tx]; tx=top[x];
    150     }
    151     if(dep[x]>dep[y]) swap(x,y);
    152     if(Pos[y]>Pos[x]) upd(Pos[x]+1,Pos[y],1,1,stp,0);
    153 }
    154 int find(int x,int y){
    155     int tx=top[x],ty=top[y];
    156     int ret=0;
    157     while(tx^ty){
    158         if(dep[tx]<dep[ty]) swap(tx,ty),swap(x,y);
    159         ret+=query(Pos[tx],Pos[x],1,1,stp);
    160         x=fa[tx]; tx=top[x];
    161     }
    162     if(dep[x]>dep[y]) swap(x,y);
    163     if(Pos[y]>Pos[x]) ret+=query(Pos[x]+1,Pos[y],1,1,stp);
    164     return ret;
    165 }
    166 void check1(){
    167     for(int i=1;i<=n;i++){
    168         cout<<"i= "<<i<<"  "<<belong[i]<<endl;
    169     } cout<<endl;
    170 //    cout<<cnt<<"   "<<stp<<endl;
    171     for(int i=1;i<=cnt;i++){
    172         cout<<"i=  "<<i<<"  "<<dep[i]<<"  "<<fa[i]<<"  "<<Pos[i]<<endl;
    173     }
    174 }
    175 void work(){
    176     memset(dfn,-1,sizeof(dfn));
    177     memset(mk,-1,sizeof(mk));
    178     tarjan(1,-1);
    179     for(int i=0;i<A.e;i++){
    180         int u=A.g[i].u, v=A.g[i].v;
    181         if(belong[u]!=belong[v]){
    182             B.add(belong[u],belong[v]);
    183         }
    184     }
    185     stp=0;
    186     dfs1(1); dfs2(1,1);
    187 //    check1();
    188     upd(2,stp,1,1,stp,1);
    189     for(int i=tip;i>=1;i--){
    190 //        cout<<"i=="<<i<<endl;
    191         if(Q[i].od){
    192             if(belong[Q[i].u]==belong[Q[i].v]){
    193                 Q[i].ans=0; continue;
    194             }
    195 //            cout<<belong[Q[i].u]<<"  "<<belong[Q[i].v]<<endl;
    196             Q[i].ans=find(belong[Q[i].u],belong[Q[i].v]);
    197         }
    198         else{
    199             if(belong[Q[i].u]==belong[Q[i].v]) continue;
    200             change(belong[Q[i].u],belong[Q[i].v]);
    201         }
    202     }
    203     for(int i=1;i<=tip;i++){
    204         if(!Q[i].od) continue;
    205         printf("%d
    ",Q[i].ans);
    206     }
    207 }
    208 int main(){
    209 //    freopen("a.in","r",stdin);
    210     init();
    211     Del_lk();
    212     work();
    213 }
    View Code
  • 相关阅读:
    一些常用的Ant标签
    c++ 精简版 scope_guard
    c++ 精简版 fps限制
    用c++11封装win32界面库
    c++ 精简版 signal
    SQL Server 数据库中的 MD5 和 SHA1加密算法
    不同服务器数据库之间的数据操作
    MSSQL行专列
    JS倒计时代码
    破解网页中限制的《七种武器》
  • 原文地址:https://www.cnblogs.com/FOXYY/p/7703476.html
Copyright © 2011-2022 走看看