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\n",Q[i].ans);
206     }
207 }
208 int main(){
209 //    freopen("a.in","r",stdin);
210     init();
211     Del_lk();
212     work();
213 }
View Code

 

posted @ 2017-10-21 06:54  Nawox  阅读(165)  评论(0编辑  收藏  举报