zoukankan      html  css  js  c++  java
  • 弱省互测#0 t3

    Case 1 题意

    要求给出下面代码的答案然后构造输入。
    给一个图, n 个点 m 条边 q 次询问,输出所有点对之间最大权值最小的路径。

    题解

    把每一个询问的输出看成一条边,建一棵最小生成树。

    Case 3 题意

    给输出,要求构造输入使得用所给代码运行后得到的输出和给出的输出相同。
    所给代码:n 次 Dijkstra 求两点间最短路

    分析

    考虑一下贪心。

    题解

    首先还是把每一条最短路的询问结果看成一条边,然后我们把这些边排序。
    对于每一条边,如果这两个点现在的距离大于这条边的权值,我们就把这条边加进去,更新所有点对
    的距离。
    正确性显然。
    现在证明这样做边数最短:
    假设这样得到的构造方案为 A ,假设还有一种构造方案是 B ,并且边数更少。
    那么在 A 中肯定存在一条边,在 B 中不存在。
    于是在 B 中,这一条边的两个端点之间的距离,肯定大于 A 中这条边的边权。
    否则如果相等的话,在 A 中就不会选择这一条边。
    因此, B 这个方案肯定是非法的,也就是说, A 是边数最少的构造方案。

    #include <bits/stdc++.h>
    using namespace std;
    
    namespace one {
    	const int N=1015, M=1000015;
    	struct E {
    		int x, y, w;
    	}e[M];
    	int p[N], n, tot, m;
    	bool cmp(const E &a, const E &b) {
    		return a.w<b.w;
    	}
    	int find(int x) {
    		return x==p[x]?x:p[x]=find(p[x]);
    	}
    	void work() {
    		scanf("%d%d", &n, &m);
    		printf("%d %d
    ", n, m);
    		int cnt=0;
    		for(int i=1; i<=n; ++i) {
    			for(int j=i+1; j<=n; ++j) {
    				e[cnt].x=i;
    				e[cnt].y=j;
    				scanf("%d", &e[cnt].w);
    				++cnt;
    			}
    		}
    		for(int i=1; i<=n; ++i) {
    			p[i]=i;
    		}
    		sort(e, e+cnt, cmp);
    		for(int i=0; i<cnt; ++i) {
    			int x=e[i].x, y=e[i].y, fx=find(x), fy=find(y), w=e[i].w;
    			if(fx!=fy) {
    				p[fx]=fy;
    				++tot;
    				printf("%d %d %d
    ", x, y, w);
    			}
    		}
    		for(; tot<=m; ++tot) {
    			printf("%d %d %d
    ", 1, 1, 0);
    		}
    	}
    }
    namespace two {
    	const int mo1=9999991, mo2=3333331;
    	typedef long long ll;
    	int ipow(int a, int b, int mo) {
    		int x=1;
    		for(; b; b>>=1, a=(ll)a*a%mo) if(b&1) x=(ll)x*a%mo;
    		return x;
    	}
    	void work() {
    		int n;
    		scanf("%d", &n);
    		printf("%d
    ", n);
    		for(int i=1; i<=n; ++i) {
    			static char s[100005];
    			scanf("%s", s+1);
    			int now1=0, now2=0, len=strlen(s+1);
    			for(int i=1; i<=len; ++i) {
    				now1=(now1*10+s[i]-'0')%mo1;
    				now2=(now2*10+s[i]-'0')%mo2;
    			}
    			for(int x=1; x<=10000; ++x) {
    				int h1=ipow(x, x, mo1), h2=ipow(x, x, mo2);
    				if(h1==now1 && h2==now2) {
    					printf("%d ", x);
    					break;
    				}
    			}
    		}
    	}
    }
    namespace three {
    	int d[1005][1005];
    	struct E {
    		int x, y, w;
    	}e[1000005];
    	bool cmp(const E &a, const E &b) {
    		return a.w<b.w;
    	}
    	void work() {
    		int n, m, cnt=0, tot=0;
    		scanf("%d%d", &n, &m);
    		printf("%d %d
    ", n, m);
    		for(int i=1; i<=n; ++i) {
    			for(int j=i+1; j<=n; ++j) {
    				e[cnt].x=i;
    				e[cnt].y=j;
    				scanf("%d", &e[cnt].w);
    				cnt++;
    			}
    		}
    		memset(d, 0x3f, sizeof d);
    		for(int i=1; i<=n; ++i) {
    			d[i][i]=0;
    		}
    		sort(e, e+cnt, cmp);
    		for(int it=0; it<cnt; ++it) {
    			int x=e[it].x, y=e[it].y, w=e[it].w;
    			if(w<d[x][y]) {
    				++tot;
    				printf("%d %d %d
    ", x, y, w);
    				d[x][y]=d[y][x]=w;
    				for(int i=1; i<=n; ++i) {
    					for(int j=1; j<=n; ++j) {
    						d[i][j]=min(d[i][j], min(d[i][x]+d[x][j], d[i][y]+d[y][j]));
    					}
    				}
    			}
    		}
    		for(; tot<=m; ++tot) {
    			printf("%d %d %d
    ", 1, 1, 1);
    		}
    	}
    }
    namespace four {
    	const int N=55005;
    	vector<int> a[N];
    	void work() {
    		int n, root;
    		scanf("%d%d", &n, &root);
    		printf("%d %d
    ", n, root);
    		int csz=0, sz=pow(n, (double)2/3);
    		for(int i=1; i<=n; ++i) {
    			int blc;
    			scanf("%d", &blc);
    			csz+=a[blc].empty();
    			a[blc].push_back(i);
    		}
    		int j, rt, na;
    		for(j=0, na=a[csz].size(); j<na; ++j) {
    			if(a[csz][j]==root) {
    				swap(a[csz][j], a[csz][0]);
    				break;
    			}
    		}
    		for(int i=csz; i>=1; --i) {
    			rt=a[i][0], j=1, na=a[i].size();
    			for(; j<sz-1 && j<na; ++j) {
    				printf("%d %d
    ", a[i][j-1], a[i][j]);
    			}
    			if(j<na) {
    				printf("%d %d
    ", a[i][j++], root);
    			}
    			for(; j<sz*2-1 && j<na; ++j) {
    				printf("%d %d
    ", a[i][j-1], a[i][j]);
    			}
    			if(j<na) {
    				printf("%d %d
    ", a[i][j++], root);
    			}
    			for(; j<na; ++j) {
    				printf("%d %d
    ", a[i][j-1], a[i][j]);
    			}
    			if(root!=rt) {
    				printf("%d %d
    ", root, rt);
    			}
    		}
    	}
    }
    namespace five {
    	const int N=100015;
    	struct E {
    		int l, r, k, w;
    	}e[N];
    	bool cmp(const E &a, const E &b) {
    		if(a.w==-1) {
    			return 0;
    		}
    		if(b.w==-1) {
    			return 1;
    		}
    		return a.w<b.w;
    	}
    	int a[N], K[N], vis[N], left, right;
    	void work() {
    		int n, t;
    		scanf("%d%d", &n, &t);
    		printf("%d %d
    ", n, t);
    		left=1; 
    		right=n;
    		int len=n/t, tot=0;
    		for(int i=0; i<t; ++i) {
    			int w;
    			scanf("%d%d", &K[i], &w);
    			if(w==-1) {
    				continue;
    			}
    			e[tot].l=i*len+1, e[tot].r=i*len+len;
    			e[tot].k=len-K[i]+1;
    			e[tot].w=w;
    			++tot;
    		}
    		sort(e, e+tot, cmp);
    		for(int i=0; i<tot; ++i) {
    			int l=e[i].l, k=e[i].k, w=e[i].w;
    			for(int j=1; j<k; ++j, ++l) {
    				while(vis[left]) {
    					++left;
    				}
    				a[l]=left;
    				vis[left]=1;
    				++left;
    			}
    			a[l]=w;
    			vis[w]=1;
    		}
    		for(int i=tot-1; i>=0; --i) {
    			int r=e[i].r, k=e[i].k;
    			for(int j=0; j<(len-k); ++j, --r) {
    				while(vis[right]) {
    					--right;
    				}
    				a[r]=right;
    				vis[right]=1;
    				--right;
    			}
    		}
    		for(int i=1; i<=n; ++i) {
    			if(a[i]) {
    				continue;
    			}
    			while(vis[right]) {
    				--right;
    			}
    			a[i]=right;
    			--right;
    		}
    		for(int i=1; i<=n; ++i) {
    			printf("%d ", a[i]);
    		}
    		for(int i=0; i<t; ++i) {
    			printf("%d ", K[i]);
    		}
    	}
    }
    int main() {
    	int C;
    	scanf("%d", &C);
    	printf("%d
    ", C);
    	if(C<20) one::work();
    	else if(C<40) two::work();
    	else if(C<60) three::work();
    	else if(C<80) four::work();
    	else five::work();
    	return 0;
    }
  • 相关阅读:
    MySQL数据库的主从同步
    学习Java必看的Java书籍(高清中文最新版附下载链接)
    servlet重点知识总结
    JUnit & JMockit单元测试
    mongodb重点知识总结
    Quartz学习总结
    IDEA使用总结
    bat脚本知识总结
    linux shell脚本相关知识
    SpringMVC重点知识总结
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4986417.html
Copyright © 2011-2022 走看看