hdu4467|zoj3742改变一个点影响到它周围的线路属性,询问整张图某属性的值(重点,轻点)
来源:互联网 发布:网络金庸群侠传怀旧版 编辑:程序博客网 时间:2024/06/10 05:28
hdu4467题意:给定N个点,M条边,每个点为0或者为1,每条边有一个权值。接下来有Q组操作,要么翻转某个点的标号,要么询问某组边的权值一共为多少,总共有三种类型的边:端点分别为(0, 0), (0, 1), (1, 1)。
zoj3742题意:给定N个点,M条边,每条边有一个权值。接下来有Q组操作,要么使某个点连接的所有边取反,要么询问正边/负边的权值和为多少。
粗粗一看两道题很像,细细推敲却觉得又不像。码着码着却又觉得很像。如果能正确发现两道题目的关联那么这一类题目都没问题了。下题相对于上题的代码只是改动了极少一部分。
坑点:同一对点直接可能有多条连线。
证明:http://www.cnblogs.com/Lyush/archive/2013/05/02/3055525.html
//题目要做的是维护00,01,11这样的边的总数,用ans[0],ans[1],ans[2]去保存 00,01(10),11的情况。复杂度大约是n/2*sqrt(m)。#include<iostream>#include<algorithm>#include<string>#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}#include<vector>#include<cmath>#include<stack>#include<string.h>#include<stdlib.h>#include<cstdio>#define ll long long using namespace std; struct node { int st; ll w0,w1; } p[100005]; struct edge { ll u,v; ll w; } e[100005],ed; int color[100005],deg[100005]; ll ans[3]; bool cmp(edge x,edge y) { if (x.u>y.u) return true; else return false; } int main() { int n,m,i,Case; ll u,v,w; char s[10]; Case=1; while (scanf("%d%d",&n,&m)!=EOF) { memset(deg,0,sizeof(deg)); for (i=1;i<=n;i++) scanf("%d",&color[i]); map<pair<ll,ll>,ll> r; for (i=1;i<=m;i++) { scanf("%I64d %I64d %I64d",&u,&v,&w); if(u>v) swap(u,v); r[{u,v}]+=w; } m=0; for(map<pair<ll,ll>,ll>::iterator it=r.begin();it!=r.end();++it){ e[++m].u=(*it).first.first; e[m].v=(*it).first.second; e[m].w=(*it).second; } ans[0]=ans[1]=ans[2]=0; for (i=1;i<=m;i++) { u=e[i].u; v=e[i].v; deg[u]++; deg[v]++; //记录度数 if (color[u]!=color[v]) ans[2]+=e[i].w; else ans[color[u]]+=e[i].w; //初始化三种情况的权值和 } for (i=1;i<=m;i++) { u=e[i].u; v=e[i].v; if (deg[u]>deg[v]) swap(e[i].u,e[i].v); } sort(e+1,e+m+1,cmp); //使u的度数小于v的度数,并排序,这样可以直接逐边处理 memset(p,0,sizeof(p)); for (i=1;i<=m;i++) { u=e[i].u; v=e[i].v; if (p[u].st==0) p[u].st=i; //记录u节点第一次出现的位置 if (color[u]) p[v].w1+=e[i].w; else p[v].w0+=e[i].w; //存储点的w0和w1 } int q; scanf("%d",&q); printf("Case %d:\n",Case++); while (q--) { int x,y; scanf("%s",s); if (s[0]=='A') { scanf("%d%d",&x,&y); if (x!=y) printf("%I64d\n",ans[2]); else printf("%I64d\n",ans[x]); //这里可以发现为什么ans的表示的巧妙 } else { scanf("%d",&x); if (color[x]) //处理小度数的 { ans[2]+=p[x].w1; ans[2]-=p[x].w0; ans[0]+=p[x].w0; ans[1]-=p[x].w1; } else { ans[2]-=p[x].w1; ans[2]+=p[x].w0; ans[0]-=p[x].w0; ans[1]+=p[x].w1; } color[x]=1-color[x]; int st=p[x].st; while (st<=m&&e[st].u==x) //大度数的 { v=e[st].v; if (color[x]!=color[v]) { ans[2]+=e[st].w; ans[1-color[x]]-=e[st].w; } else { ans[color[x]]+=e[st].w; ans[2]-=e[st].w; } if (color[x]==0) { p[v].w0+=e[st].w; p[v].w1-=e[st].w; } else { p[v].w0-=e[st].w; p[v].w1+=e[st].w; } st++; } } } } return 0; }
#include<iostream>#include<algorithm>#include<string>#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}#include<vector>#include<cmath>#include<stack>#include<string.h>#include<stdlib.h>#include<cstdio>#define ll long long using namespace std; struct node{ int st; ll w0[2],w1[2];node(){memset(w0,0,sizeof(w0));memset(w1,0,sizeof(w1));} } p[50005]; struct edge{ int u,v; ll w; } e[50005];int color[50005],deg[50005];ll ans[3][2];bool cmp(edge x,edge y) { if (x.u>y.u) return true; else return false; } int main() { int n,m,q,i; int u,v,w; char s[2]; int ok=0; while (scanf("%d%d%d",&n,&m,&q)!=EOF) { if(ok==0) ok=1; else printf("\n"); memset(color,0,sizeof(color)); memset(deg,0,sizeof(deg)); map<pair<int,int>,ll> r; memset(ans,0,sizeof(ans)); for (i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); if(u>v) swap(u,v); if (color[u]!=color[v]){ if(w>0) ans[2][0]+=w; else ans[2][1]+=w; } else{ if(w>0) ans[color[u]][0]+=w; elseans[color[u]][1]+=w; //初始化三种情况的权值和 } r[{u,v}]+=w; } m=0; for(map<pair<int,int>,ll>::iterator it=r.begin();it!=r.end();++it){ e[++m].u=(*it).first.first; e[m].v=(*it).first.second; e[m].w=(*it).second; } for (i=1;i<=m;i++) { u=e[i].u; v=e[i].v; deg[u]++; deg[v]++; //记录度数 } for (i=1;i<=m;i++) { u=e[i].u; v=e[i].v; if (deg[u]>deg[v]) swap(e[i].u,e[i].v); } sort(e+1,e+m+1,cmp); //使u的度数小于v的度数,并排序,这样可以直接逐边处理 memset(p,0,sizeof(p)); for (i=1;i<=m;i++) { u=e[i].u; v=e[i].v; if (p[u].st==0) p[u].st=i; //记录u节点第一次出现的位置 if (color[u]){ if(e[i].w>0) p[v].w1[0]+=e[i].w; else p[v].w1[1]+=e[i].w; } else{ //存储点的w0和w1 if(e[i].w>0) p[v].w0[0]+=e[i].w; else p[v].w0[1]+=e[i].w; } } while (q--) { int x,y; scanf("%s",s); if (s[0]=='Q') { char c[2]; scanf("%s",c); if(c[0]=='+') cout<<ans[0][0]+ans[1][0]-ans[2][1]<<endl; else if(c[0]=='-') cout<<ans[0][1]+ans[1][1]-ans[2][0]<<endl; else cout<<ans[0][0]+ans[1][0]-ans[2][1]+ans[0][1]+ans[1][1]-ans[2][0]<<endl; } else { scanf("%d",&x); if (color[x]) //处理小度数的 { ans[2][1]+=p[x].w1[1]; ans[2][0]+=p[x].w1[0]; ans[2][0]-=p[x].w0[0]; ans[2][1]-=p[x].w0[1]; ans[0][0]+=p[x].w0[0]; ans[0][1]+=p[x].w0[1]; ans[1][1]-=p[x].w1[1]; ans[1][0]-=p[x].w1[0]; } else { ans[2][1]-=p[x].w1[1]; ans[2][0]-=p[x].w1[0]; ans[2][0]+=p[x].w0[0]; ans[2][1]+=p[x].w0[1]; ans[0][0]-=p[x].w0[0]; ans[0][1]-=p[x].w0[1]; ans[1][1]+=p[x].w1[1]; ans[1][0]+=p[x].w1[0]; } color[x]=1-color[x]; int st=p[x].st; while (st<=m&&e[st].u==x) //大度数的 { v=e[st].v; if (color[x]!=color[v]) { if(e[st].w>0){ ans[2][0]+=e[st].w; ans[1-color[x]][0]-=e[st].w; } else{ ans[2][1]+=e[st].w; ans[1-color[x]][1]-=e[st].w; } } else { if(e[st].w>0){ ans[color[x]][0]+=e[st].w; ans[2][0]-=e[st].w; }else{ans[color[x]][1]+=e[st].w; ans[2][1]-=e[st].w; } } if (color[x]==0) { if(e[st].w>0) p[v].w0[0]+=e[st].w; else p[v].w0[1]+=e[st].w; if(e[st].w>0) p[v].w1[0]-=e[st].w; else p[v].w1[1]-=e[st].w; } else { if(e[st].w>0) p[v].w0[0]-=e[st].w; else p[v].w0[1]-=e[st].w; if(e[st].w>0) p[v].w1[0]+=e[st].w; else p[v].w1[1]+=e[st].w; } st++; } } } } return 0; }
0 0
- hdu4467|zoj3742改变一个点影响到它周围的线路属性,询问整张图某属性的值(重点,轻点)
- 子div的margin属性影响到父div的定位
- servlet属性值的改变;
- hdu4467 Graph(图的分块)
- 改变文件的属性
- 监听属性的改变
- 属性动画的改变
- CSS的float属性对周围元素位置的影响
- 去掉点击链接时周围的虚线框outline属性
- Android开发周围wifi热点和属性的获取
- 去掉点击链接时周围的虚线框outline属性
- Android开发周围wifi热点和属性的获取
- 属性以及它的特性
- 关于改变一个文件夹下的所有文件的属性
- 代码改变EditText的password属性值
- 代码改变EditText的password属性值
- 代码改变EditText的password属性值
- 代码改变EditText的password属性值
- 蓝桥杯+金蝉素数
- A,B,C类IP地址的解说
- rails ajax
- 哈工大语言云(LTP)本地安装使用及Python调用
- HOOK钩子机制
- hdu4467|zoj3742改变一个点影响到它周围的线路属性,询问整张图某属性的值(重点,轻点)
- string的常用方法
- 几大主流浏览器性能比较
- opengl学习之三:OpenGL基本功能
- 时间序列分析及应用 R语言 读书笔记 03
- 合并表记录
- IP地址的分类——a,b,c 类是如何划分的
- Scala下划线“_”的用法
- C++面向对象的抽象 封装继承 多态总结