8.13模拟赛
T1 HOTEL
题目大意:
在树上选出三个点使这三个两两之间距离相等 求选出这三个点的方案
思路:
树形dp
枚举每一个树根 选三个和选两个差不多 多开一个dp数组
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<set> 10 #define MAXN 5010 11 #define ll long long 12 #define inf 2139062143 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int n,fst[MAXN],to[MAXN<<1],nxt[MAXN<<1],cnt,dep[MAXN]; 22 ll tmp[MAXN],dp[MAXN][2],ans; 23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;} 24 void dfs(int x,int fa) 25 { 26 tmp[dep[x]]++; 27 for(int i=fst[x];i;i=nxt[i]) 28 if(to[i]!=fa) {dep[to[i]]=dep[x]+1;dfs(to[i],x);} 29 } 30 int main() 31 { 32 n=read();int a,b; 33 for(int i=1;i<n;i++){a=read(),b=read();add(a,b);add(b,a);} 34 for(int x=1;x<=n;x++) 35 { 36 memset(dp,0,sizeof(dp)); 37 for(int i=fst[x];i;i=nxt[i]) 38 { 39 dep[to[i]]=1;dfs(to[i],x); 40 for(int j=1;j<=n;j++) 41 ans+=dp[j][0]*tmp[j],dp[j][0]+=dp[j][1]*tmp[j],dp[j][1]+=tmp[j]; 42 memset(tmp,0,sizeof(tmp)); 43 } 44 } 45 printf("%lld",ans); 46 }
T2 Chips Challenge
题目大意:
有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件。
有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意。
要求装好之后满足如下两条要求:
1、第 i 行和第 i 列的零件数目必须一样多(1≤i≤N)。
2、第 i 行的零件数目不能超过总的零件数目的 A/B(1≤i≤N,0≤A≤B≤1000,B≠0)。
求最多可以另外放多少个零件 如果无解输出impossible
思路:
T3 Mst
题目大意:
给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树
思路:
先搞出最小生成树
如果删的边不是树边 不影响
如果是即我们需要一条非树边将这两个联通块联通,可以将所有非树边按照从大至小的顺序,将这个边的两个端点在树上的路径的答案修改为该边的权值
每次询问的时候查询这条边的答案
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<set> 10 #define MAXN 50100 11 #define ll long long 12 #define inf 2139062143 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int n,m,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt,etr[MAXN<<1],hvs[MAXN]; 22 int fa[MAXN],trs[MAXN<<1],hsh[MAXN],sz[MAXN],dep[MAXN],bl[MAXN],ans,f; 23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;} 24 struct edge{int u,v,val,id;}e[MAXN<<1]; 25 bool cmp(edge a,edge b) {return a.val<b.val;} 26 int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);} 27 bool ok(int a,int b) 28 { 29 int f1=find(a),f2=find(b); 30 if(f1!=f2) {fa[f1]=f2;return 0;} 31 return 1; 32 } 33 void kruskal(int res) 34 { 35 sort(e+1,e+m+1,cmp); 36 for(int i=1;i<=m;i++) 37 if(!ok(e[i].u,e[i].v)) {res++,ans+=e[i].val;add(e[i].u,e[i].v);add(e[i].v,e[i].u);trs[e[i].id]=i,etr[i]=1;} 38 if(res!=n-1) f=1; 39 } 40 void dfs(int x) 41 { 42 sz[x]=1,dep[x]=dep[fa[x]]+1; 43 for(int i=fst[x];i;i=nxt[i]) 44 if(to[i]!=fa[x]) {fa[to[i]]=x;dfs(to[i]);sz[x]+=sz[to[i]];} 45 } 46 void Dfs(int x,int anc) 47 { 48 hsh[x]=++cnt,bl[x]=anc; 49 for(int i=fst[x];i;i=nxt[i]) 50 if(dep[to[i]]>dep[x]&&sz[hvs[x]]<sz[to[i]]) hvs[x]=to[i]; 51 if(!hvs[x]) {hvs[x]=x;return ;}Dfs(hvs[x],anc); 52 for(int i=fst[x];i;i=nxt[i]) 53 if(dep[to[i]]>dep[x]&&to[i]!=hvs[x]) {Dfs(to[i],to[i]);} 54 } 55 int mn[MAXN<<2],tag[MAXN<<2]; 56 void pshd(int k,int l,int r,int mid) 57 { 58 tag[k<<1]=tag[k<<1|1]=tag[k]; 59 mn[k<<1]=tag[k],mn[k<<1|1]=tag[k],tag[k]=0; 60 } 61 void mdf(int k,int l,int r,int a,int b,int x) 62 { 63 if(l==a&&r==b) {mn[k]=tag[k]=x;return ;} 64 int mid=(l+r)>>1; 65 if(tag[k]) pshd(k,l,r,mid); 66 if(mid>=b) mdf(k<<1,l,mid,a,b,x); 67 else if(mid<a) mdf(k<<1|1,mid+1,r,a,b,x); 68 else {mdf(k<<1,l,mid,a,mid,x);mdf(k<<1|1,mid+1,r,mid+1,b,x);} 69 mn[k]=min(mn[k<<1],mn[k<<1|1]); 70 } 71 int query(int k,int l,int r,int x) 72 { 73 if(l==r) return mn[k]; 74 int mid=(l+r)>>1; 75 if(tag[k]) pshd(k,l,r,mid); 76 if(mid>=x) return query(k<<1,l,mid,x); 77 else query(k<<1|1,mid+1,r,x); 78 } 79 void tr_mdf(int a,int b,int x) 80 { 81 while(bl[a]!=bl[b]) 82 { 83 if(dep[bl[a]]<dep[bl[b]]) swap(a,b); 84 mdf(1,1,n,hsh[bl[a]],hsh[a],x); 85 a=fa[bl[a]]; 86 } 87 if(dep[a]<dep[b]) swap(a,b); 88 if(a!=b) mdf(1,1,n,hsh[hvs[b]],hsh[a],x); 89 } 90 int main() 91 { 92 n=read(),m=read(); 93 for(int i=1;i<=n;i++) fa[i]=i; 94 for(int i=1;i<=m;i++) e[i].id=i,e[i].u=read(),e[i].v=read(),e[i].val=read(); 95 kruskal(0);fa[1]=1;dfs(1);cnt=0;Dfs(1,1);int T=read(),x; 96 if(!f) for(int i=m;i;i--) if(!etr[i]) tr_mdf(e[i].u,e[i].v,e[i].val); 97 while(T--) 98 { 99 x=trs[read()]; 100 if(f) {puts("Not connected");continue;} 101 if(etr[x]) 102 { 103 if(query(1,1,n,max(hsh[e[x].u],hsh[e[x].v]))) printf("%d\n",ans-e[x].val+query(1,1,n,max(hsh[e[x].u],hsh[e[x].v]))); 104 else puts("Not connected"); 105 } 106 else printf("%d\n",ans); 107 } 108 }