2018 BUPT Winter Training #8 Div.2
2018-03-07 23:11
225 查看
A - 无向图最小生成树
表白月加大佬,真是体贴萌新(笑)最小生成树模板(话说是不是和之前树专题撞题了..)
#include <cstdio> #include <vector> #include <queue> #include <utility> #define TRV(_i,_V) for(int _i=(_V).size()-1;_i+1;_i--) #define 15d0c PB push_back #define MP make_pair #define sec second #define fir first using namespace std; typedef pair<int,int> pii; vector<pii> E[1005]; bool vis[1005]={0}; priority_queue<pii,vector<pii>,greater<pii> >q; pii tem; int main(){ int N,M,u,v,val; scanf("%d%d",&N,&M); for(int i=0;i<M;i++){ scanf("%d%d%d",&u,&v,&val); E[u].PB(MP(val,v));E[v].PB(MP(val,u)); } int ans=0; q.push(MP(0,1)); while(!q.empty()){ tem=q.top();q.pop(); if(vis[tem.sec])continue; vis[tem.sec]=1; ans+=tem.fir; TRV(i,E[tem.sec]){ if(!vis[E[tem.sec][i].sec])q.push(E[tem.sec][i]); } } printf("%d",ans); }
B - Arbitrage
单源最短路径判正反馈环。#include <iostream> #include <cstring> #include <string> #include <map> #include <vector> #include <utility> #define TRV(_i,_V) for(int _i=(_V).size()-1;_i+1;_i--) #define PB push_back #define MP make_pair #define sec second #define fir first #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) using namespace std; string name,na2; map<string,int> currName; struct edge{ int u,v; double w; edge(){} edge(int _u,int _v,double _w){u=_u;v=_v;w=_w;} }; vector<edge> E; int Esize,n; double dist[35]; bool bellman_ford(int start){ bool released=0; memset(dist,0,sizeof(dist)); dist[start]=1; FF(i,2,n){ released=0; F(j,Esize){ if(dist[E[j].v]<dist[E[j].u]*E[j].w){ dist[E[j].v]=dist[E[j].u]*E[j].w; released=1; } } if(!released)return 0; } F(j,Esize)if(dist[E[j].v]<dist[E[j].u]*E[j].w)return 1; return 0; } int main(){ int id1,id2,cas=1; double w; bool ZhuanDaRe; ios::sync_with_stdio(false); while(cin>>n){ if(!n)break; E.clear(); ZhuanDaRe=0; FF(i,1,n){cin>>name;currName[name]=i;} cin>>Esize; F(i,Esize){ cin>>name>>w>>na2; E.PB(edge(currName[name],currName[na2],w)); } FF(i,1,n)if(ZhuanDaRe|=bellman_ford(i))break; cout<<"Case "<<cas++<<": "<<(ZhuanDaRe?"Yes":"No")<<endl; } }
C - Starry Night
(敲黑板)自创hash函数(可把我牛逼坏了?虽然前面还有几位大佬比我用的内存更少,太牛逼了!)这个hash函数的特点是可以使得直角旋转变换的相同图片拥有相同的hash值。hash(G)=∑p∈G(pxpy(maxx−px)(maxy−py)+hash_prime)hash(G)=∑p∈G(pxpy(maxx−px)(maxy−py)+hash_prime)
#include <cstdio> #include <map> #include <queue> #include <vector> #include <cstring> #define TRV(_i,_V) for(int _i=(_V).size()-1;_i+1;_i--) #define PB push_back #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) #define MP make_pair #define sec second #define fir first using namespace std; typedef pair<int,int> pii; int wayx[]={-1,-1,-1,0,0,1,1,1},wayy[]={-1,0,1,-1,1,-1,0,1}; char star[105][105]; int R,C,minx,miny,maxx,maxy,cluster=1; vector<pii> E; void dfsgetE(int y,int x){ star[y][x]='0'; E.PB(MP(y,x)); if(minx>x)minx=x; if(miny>y)miny=y; if(maxx<x)maxx=x; if(maxy<y)maxy=y; int tx,ty; F(i,8){ tx=wayx[i]+x;ty=wayy[i]+y; if(tx&&ty&&tx<=C&&ty<=R){ if(star[ty][tx]=='1')dfsgetE(ty,tx); } } } map<unsigned int,int> hashmap; void work(int y,int x){ maxx=maxy=-1;minx=C+1,miny=R+1; E.clear(); dfsgetE(y,x); minx--;miny--; maxx-=minx;maxy-=miny; maxx++;maxy++; unsigned int hash=0; TRV(i,E){ y=E[i].fir-miny;x=E[i].sec-minx; hash+=233+(maxx-x)*(maxy-y)*x*y; } if(!hashmap[hash])hashmap[hash]=cluster++; x=hashmap[hash]; TRV(i,E)star[E[i].fir][E[i].sec]=x-1+'a'; } int main(){ memset(star,0,sizeof(star)); scanf("%d%d",&C,&R); FF(i,1,R)scanf("%s",star[i]+1); FF(i,1,R){ //y ,x FF(j,1,C)if(star[i][j]=='1')work(i,j); } FF(i,1,R)printf("%s\n",star[i]+1); }
D - 迷宫游戏
最小生成树的扩展,cmp函数变化一下而已。#include <cstdio> #include <cstring> #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) #define MO 1061109567 using namespace std; const int N = 505; int t ,w ,dist ,score ={0}; bool vis ={0}; int main(){ int n,m,s,e,u,v; memset(t,0x3f,sizeof(t)); memset(dist,0x3f,sizeof(dist)); scanf("%d%d%d%d",&n,&m,&s,&e); F(i,n)scanf("%d",&w[i]); F(i,m){ scanf("%d%d",&u,&v); scanf("%d",&t[u][v]); t[v][u]=t[u][v]; } dist[s]=0;score[s]=w[s]; int min,mini; F(i,n){ min=MO; F(j,n)if(!vis[j]&&min>dist[j])min=dist[mini=j]; vis[mini]=1; F(j,n){ if(dist[mini]+t[mini][j]<dist[j]||dist[mini]+t[mini][j]==dist[j]&&score[mini]+w[j]>score[j]){ dist[j]=dist[mini]+t[mini][j]; score[j]=score[mini]+w[j]; } } } printf("%d %d",dist[e>>>>>> ,score[e]); }
E - 贫富差距
若图不连通,直接wrong,然后就是求最近距离了#include <iostream> #include <cstring> #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) #define MO 1061109567 using namespace std; const int N = 50; int dist[N+5][N+5],n; const int DS_size=N; int pre[DS_size+5]; int siz[DS_size+5]; inline void init(int n){ for(int i=1;i<=n;i++)siz[pre[i]=i]=1; } inline int find(int x){ return x==pre[x]?x:pre[x]=find(pre[x]); } inline int size(int x){ return siz[find(x)]; } void uni(int x,int y){ dist[x][y]=1; if((x=find(x))!=(y=find(y))){ if(siz[x]>siz[y])siz[pre[y]=x]+=siz[y]; else siz[pre[x]=y]+=siz[x]; } } int main(){ int T,d,ans;char c; ios::sync_with_stdio(false); for(cin>>T;T--;){ memset(dist,0x3f,sizeof(dist)); cin>>n>>d; FF(i,1,n)dist[i][i]=0; init(n); FF(i,1,n)FF(j,1,n){ cin>>c; if(c=='Y')uni(i,j); } if(size(1)<n){ cout<<-1<<endl; continue; } FF(k,1,n)FF(i,1,n)FF(j,1,n){ if(dist[i][j]>dist[i][k]+dist[k][j]) dist[i][j]=dist[i][k]+dist[k][j]; } ans=0; FF(i,1,n)FF(j,1,n){ if(dist[i][j]!=MO&&ans<dist[i][j])ans=dist[i][j]; } cout<<ans*d<<endl; } }
F - 畅通工程续
最小生成树模板题。#include <iostream> #include <cstring> #include <vector> #define TRV(_i,_V) for(int _i=(_V).size()-1;_i+1;_i--) #define PB push_back #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) #define MO 1061109567 using namespace std; struct edge{ int u,v,w; edge(){} edge(int _u,int _v,int _w){u=_u;v=_v;w=_w;} }; vector<edge> E; int n,m; int dist[205]; bool bellman_ford(int start){ bool released=0; memset(dist,0x3f,sizeof(dist)); dist[start]=0; FF(i,2,n){ released=0; F(j,m){ if(dist[E[j].v]>dist[E[j].u]+E[j].w){ dist[E[j].v]=dist[E[j].u]+E[j].w; released=1; } } if(!released)return 0; } //F(j,m)if(dist[E[j].v]<dist[E[j].u]*E[j].w)return 1; return 0; } int main(){ int u,v,w; ios::sync_with_stdio(false); while(cin>>n>>m){ E.clear(); F(i,m){ cin>>u>>v>>w; E.PB(edge(u,v,w)); E.PB(edge(v,u,w)); } m<<=1; cin>>u>>v; bellman_ford(u); cout<<(dist[v]==MO?-1:dist[v])<<endl; } }
G - 2条不相交的路径
考虑到Query的规模到达1e5,要用tarjan算法离线判断双连通分量#include <cstdio> #include <cstring> #include <vector> #define TRV(_i,_V) for(int _i=(_V).size()-1;_i+1;_i--) #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) #define PB push_back using namespace std; const int N=50000; vector<int> E[N+5]; int dfsc,Tarjan_top,Cir; int low[N+5],dfn[N+5]; int Tarjan_stack[N+5],preCir[N+5]; bool Tarjan_ins[N+5]; void init(int n){ dfsc=1; Tarjan_top=Cir=0; memset(Tarjan_ins,0,sizeof(Tarjan_ins)); memset(low,0,sizeof(low)); memset(preCir,0,sizeof(preCir)); memset(dfn,0,sizeof(dfn)); FF(i,1,n)E[i].clear(); } void Tarjan(int u,int last){ int v; Tarjan_ins[Tarjan_stack[Tarjan_top++]=u]=1; low[u]=dfn[u]=dfsc++; TRV(i,E[u]){ v=E[u][i]; if(!dfn[v]){ Tarjan(v,u); if(low[v]<low[u])low[u]=low[v]; }else if(v!=last&&Tarjan_ins[v]&&dfn[v]<low[u])low[u]=dfn[v]; } if(dfn[u]==low[u]){ Cir++; do{ preCir[v=Tarjan_stack[--Tarjan_top]]=Cir; Tarjan_ins[v]=0; }while(Tarjan_top>0&&v!=u); } } int main(){ int m,n,u,v; init(n); scanf("%d%d",&m,&n); F(i,n){ scanf("%d%d",&u,&v); E[u].PB(v);E[v].PB(u); } FF(i,1,n)if(!dfn[i])Tarjan(i,-1); int Q; scanf("%d",&Q); F(q,Q){ scanf("%d%d",&u,&v); puts((preCir[u]==preCir[v])?"Yes":"No"); } }
H - 天气晴朗的魔法
求最小生成树最大边权下的最大生成树。#include <cstdio> #include <vector> #include <algorithm> #define INTMAX 0x7fffffff #define TRV(_i,_V) for(int _i=(_V).size()-1;_i+1;_i--) #define all(x) x.begin(),x.end() #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) #define PB push_back using namespace std; struct edge{ int u,v; int w; edge(){} edge(int _u,int _v,int _w){u=_u;v=_v;w=_w;} }; const int N=100000; vector<edge> E; bool vis[N+5]={0}; bool cmp(edge x,edge y){ return x.w>y.w; } const int DS_size=N; int pre[DS_size+5]; int siz[DS_size+5]; inline void init(int n){ for(int i=1;i<=n;i++)siz[pre[i]=i]=1; } inline int find(int x){ return x==pre[x]?x:pre[x]=find(pre[x]); } inline int size(int x){ return siz[find(x)]; } bool uni(int x,int y){ if((x=find(x))!=(y=find(y))){ if(siz[x]>siz[y])siz[pre[y]=x]+=siz[y]; else siz[pre[x]=y]+=siz[x]; return 1; } return 0; } int main(){ int N,M,u,v,val; scanf("%d%d",&N,&M); init(N); for(int i=0;i<M;i++){ scanf("%d%d%d",&u,&v,&val); E.PB(edge(u,v,val)); } sort(all(E),cmp); int maxw=-INTMAX; long long ans=0; TRV(i,E){ if(uni(E[i].u,E[i].v)&&maxw<E[i].w)maxw=E[i].w; } init(N); F(i,M){ if(E[i].w>maxw)continue; if(uni(E[i].u,E[i].v))ans+=E[i].w; } printf("%lld",ans); }
相关文章推荐
- 2018 BUPT Winter Training #7 Div.2
- 2018 BUPT Winter Training #6 Div.2
- 2018 BUPT Winter Training #1 div.2
- 2018 BUPT Winter Training #2 Div.2
- 2018 BUPT Winter Training #3 Div.2
- 2018 BUPT Winter Training #4 Div.2
- 2018 BUPT Winter Training #5 Div.2
- codeforces hellow 2018 div.2
- 2018 BUPT Winter Training #1 div.1
- 2017-2018-1 20155230 mypwd实现
- 20162329 2017-2018-1 《程序设计与数据结构》第十一周学习总结
- 04/08/2018 笔记
- 2017-2018-1 20155218 《信息安全系统设计基础》第九周学习总结
- BlackHat Arsenal USA 2018 ToolsWatch黑客工具库
- 网易2018校招内推编程题集合:交错01串 [python]
- 2018web前端不好找工作之web前端面试简历补救篇
- HDU - 2018母牛的故事 - 递推
- 【Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) C】
- 企服三会·PPT | 中国软件网曹开彬:洞见2018中国移动办公趋势洞察报告