标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5813
题意是:有n个点,每个点都能到达num个点,让我们构造任意一个有向图满足条件,即:使得 i 能到达 a[i] 个点;
将顶点按能到达的点数从小到大排序,排好序之后每个点只能往前面的点连边. 所以我们必须要让前面点的个数大于或等于它要连得点的个数;
因而如果存在一个排在第i位的点(前面有i-1个点),i-1>=要求到达的点数(i>要求到达的点数);
按照上述方法构造出图. 复杂度O(N^2).
#include <cstring> #include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <stack> #include <vector> #include <queue> using namespace std; #define N 1005 #define met(a, b) memset(a, b, sizeof(a)) typedef long long LL; struct node { int Id, num; friend bool operator < (node p, node q) { return p.num < q.num; } }a[N]; int u[N*N], v[N*N]; int main() { int T, t = 1, n; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i=1; i<=n; i++) { scanf("%d", &a[i].num); a[i].Id = i; } sort(a+1, a+n+1); int k = 0, flag = 0; for(int i=n; i>=1; i--) { if(a[i].num >= i)///前面点的个数必须要大于它要到达的点的个数; { flag = 1; break; } for(int j=1; j<=a[i].num; j++)///由于只需输出一组符合条件的解即可,所以我们可以用a[i].Id连接num条任意的a[j].Id(j < i); { u[k] = a[i].Id; v[k++] = a[j].Id; } } if(flag) printf("Case #%d: No\n", t++); else { printf("Case #%d: Yes\n", t++); printf("%d\n", k); for(int i=0; i<k; i++) printf("%d %d\n", u[i], v[i]); } } return 0; } /* 3 3 2 1 0 2 1 1 4 3 1 1 0 */
Elegant Construction---hdu5813(构造图)
标签:
原文地址:http://www.cnblogs.com/zhengguiping--9876/p/5755952.html