2013-2014 Northwestern European Regional Contest (NWERC 2013)
2016-09-07 21:31
671 查看
http://codeforces.com/gym/100405/
补题:
Idea 1:
删边法。时间接近于O(n^3 )。根据题目中给的矩阵构造一个完全图,然后遍历每条边,看是否需这条边是多余的。如果某条边的两点间的最短路可以由其他点到达,那么这条边就是多余的,可删除。因为保证有解,所以最后这张图里面要么有n条边,要么有n-1条边。最后处理一下即可。
Idea2:
将所有的边排序然后做一次最小生成树,O(nlogn)。然后最后在这个图上加一条边。先DFS遍历这个图,计算两点的距离,看是否是最短路。如果是不是最短路,增加本应该最短的那条路。
DFS爆搜即可。因为符合情况的最大团只有三种情况,要么两个点,要么三个点,要么四个点。。
补题:
A
已知一个图的点数为n,且改图为连通图。告诉了每两个点之间的最短路的距离。让你构造这个图,且这个图的边数为n。Idea 1:
删边法。时间接近于O(n^3 )。根据题目中给的矩阵构造一个完全图,然后遍历每条边,看是否需这条边是多余的。如果某条边的两点间的最短路可以由其他点到达,那么这条边就是多余的,可删除。因为保证有解,所以最后这张图里面要么有n条边,要么有n-1条边。最后处理一下即可。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 2050; int mp ; bool is ; int main() { int n; bool flag = false; while(scanf("%d",&n)!=EOF) { if(flag) printf("\n"); flag = true; memset(is,true,sizeof(is)); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&mp[i][j]); for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { for(int k=1;k<=n;k++) { if(k==i || k==j) continue; if(mp[i][j] == mp[i][k]+mp[k][j]) { is[i][j] = false; break; } } } } int cnt = 0; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if( is[i][j]) { printf("%d %d %d\n",i,j,mp[i][j]); cnt ++; } } } if(cnt==n -1) printf("%d %d %d\n",1,2,mp[1][2]); } return 0; }
Idea2:
将所有的边排序然后做一次最小生成树,O(nlogn)。然后最后在这个图上加一条边。先DFS遍历这个图,计算两点的距离,看是否是最短路。如果是不是最短路,增加本应该最短的那条路。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int N = 2050; struct Node { int u,v,x; Node(){} Node(int a,int b,int c):u(a),v(b),x(c){} friend bool operator < (const Node a,const Node b) { return a.x < b.x; } }edg[N*N]; int gra , father , dep ,root ; vector<int> vet ; bool vis ; int find(int x) { int y = x; while(y!=father[y]) y = father[y]; while(x!=father[x]) { int px = father[x]; father[x] = y; x = px; } return y; } void dfs(int u,int time,int fa) { dep[u] = time; root[u] = fa; vis[u] = true; for(int i=0; i<vet[u].size();i++) { int v = vet[u][i]; if(vis[v]) continue; dfs(v,time+1,u); } } int LCA(int x,int y) { int tmp = 0; while(x != y ) { if(dep[x] > dep[y]) { int px = x; x = root[x]; tmp += gra[px][x]; } else { int py = y; y = root[y]; tmp+=gra[py][y]; } } return tmp; } int main() { int n; bool flag = false; while(scanf("%d",&n)!=EOF) { if(flag) printf("\n"); flag = true; int tot = 0; for(int i=1;i<=n;i++) { father[i] = i; root[i] = i; vet[i].clear(); for(int j=1;j<=n;j++) { scanf("%d",&gra[i][j]); if(i>j) edg[tot++] = Node(i,j,gra[i][j]); } } sort(edg,edg+tot); for(int i=0; i<tot;i++) { int x = edg[i].u; int y = edg[i].v; int fx = find(x); int fy = find(y); if(fx==fy) continue; father[fx] = fy; vet[x].push_back(y); vet[y].push_back(x); printf("%d %d %d\n",x,y,edg[i].x); } memset(vis,false,sizeof(vis)); dfs(1,0,1); int ans = 0x3f3f3f3f, x=1 , y=2; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { int dis = LCA(i,j); if(dis == gra[i][j]) continue; if( gra[i][j] < ans) ans = gra[i][j], x = i, y = j; } } printf("%d %d %d\n",x,y,gra[x][y]); } return 0; }
B
给一个无向图,每个节点都有个权值。找出该图的一个最大团,且最大团内保证路径没有交叉。DFS爆搜即可。因为符合情况的最大团只有三种情况,要么两个点,要么三个点,要么四个点。。
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> using namespace std; const int N = 500; vector<int> vet ; int arr ,ans,path ; bool is ,vis ; void dfs(int u,int id,int nans) { ans = max(ans,nans); if( id >=4 ) return; for(int i=0; i<vet[u].size();i++) { int v = vet[u][i], j; if(vis[v]) continue; for(j=1;j<=id;j++) { if(!is[v][path[j]]) break; } if(j<=id) continue; vis[v] = true; path[id+1] = v; dfs(v,id+1,nans+arr[v]); vis[v] = false; } return; } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) scanf("%d",&arr[i]),vet[i].clear(); memset(is,false,sizeof(is)); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); vet[u].push_back(v); vet[v].push_back(u); is[u][v] = is[v][u] = true; } ans = 0; for(int i=1;i<=n;i++) { memset(vis,false,sizeof(vis)); vis[i] = true; path[1] = i; dfs(i,1,arr[i]); } printf("%d\n",ans); } return 0; }
G
水。#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } int main() { int a,b,c; while (~scanf("%d%d%d",&a,&b,&c)){ int x=a*b; int y=c-b; //cout<<x<<" "<<y<<endl; int w=gcd(x,y); printf("%d/%d\n",x/w,y/w); } return 0; }
F
两种日历的表示方法,同时对应着两种计算闰年的方式。问之前日历的日期对应现在日历的日期。相关文章推荐
- 2012-2013 Northwestern European Regional Contest (NWERC 2012)【solved:6 / 11】
- 2014-2015 Northwestern European Regional Contest (NWERC 2014)【solved:7 / 11】
- 2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
- 2017-2018 Northwestern European Regional Contest (NWERC 2017)
- codeforces Gym - 101485 D Debugging (2015-2016 Northwestern European Regional Contest (NWERC 2015))
- codeforces Gym - 101485 A (2015-2016 Northwestern European Regional Contest (NWERC 2015))
- E - Elementary Math 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- I - Identifying Map Tiles 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- J - Jumbled Communication 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- 2013-2014 ACM ICPC Central European Regional Contest (CERC 13) I题Crane
- C-Cleaning Pipes(判断两线段相交+二分图判定) 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- 2013-2014 ACM ICPC Central European Regional Contest (CERC 13) B题What does the fox say?
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) E
- D - Debugging 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) 补题
- 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) 7/11 待补
- Codeforces-20152016-northwestern-european-regional-contest-nwerc-A题
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) E. Elementary Math
- 2013-2014 ACM ICPC Central European Regional Contest (CERC 13) K题(dp)