我觉得题目就是给我扫盲算法的。我明白了我菜鸡我这就滚。。。。Orz。
Points on Cycle
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
There is a cycle with its center on the origin.
Now give you a point on the cycle, you are to find out the other two points on it, to maximize the sum of the distance between each other
you may assume that the radius of the cycle will not exceed 1000.
Input
There are T test cases, in each case there are 2 decimal number representing the coordinate of the given point.
Output
For each testcase you are supposed to output the coordinates of both of the unknow points by 3 decimal places of precision
Alway output the lower one first(with a smaller Y-coordinate value), if they have the same Y value output the one with a smaller X.
Sample Input
2 1.500 2.000 563.585 1.251
Sample Output
0.982 -2.299 -2.482 0.299 -280.709 -488.704 -282.876 487.453
Source
2007省赛集训队练习赛(1)
用角度算,,,但是大佬说防止误差尽量少用函数。
#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
double angle, pi, x0, y0, x1, y1, x2, y2, r, eps;
int t;
pi = acos(-1);
eps = 0.0005;
cin >> t;
while(t--){
cin >> x0 >> y0;
r = sqrt(x0 * x0 + y0 * y0);
angle = acos(x0 / r);
if(!fabs(y0) <= eps && y0 < 0){
angle = 2 * pi - angle;
}
x1 = r * cos(angle + 2.0 * pi / 3.0);
x2 = r * cos(angle - 2.0 * pi / 3.0);
y1 = r * sin(angle + 2.0 * pi / 3.0);
y2 = r * sin(angle - 2.0 * pi / 3.0);
if(angle >= pi / 2.0 && angle < 3.0 * pi / 2.0)
printf("%.3lf %.3lf %.3lf %.3lf\n",x1,y1,x2,y2);
else
printf("%.3lf %.3lf %.3lf %.3lf\n",x2,y2,x1,y1);
}
return 0;
}
还有个手推的坐标系的方程,WA了,应该是精度损失了。
#include <bits/stdc++.h>
using namespace std;
int main()
{
double x0, y0, k, r2, m, a, b, c, q, x1, x2, y1, y2;
int t;
const double eps = 0.0005;
cin >> t;
while(t--){
cin >> x0 >> y0;
k = -1 * x0 / y0;
m = k * x0 - y0;
r2 = x0 * x0 + y0 * y0;
a = r2 / (y0 * y0);//k^2 + 1
b = m * k;//2mk
c = (m * m) - r2 * 4;//4c
q = sqrt(b * b - a * c);
x1 = (-b + q) * (y0 * y0)/ (2 * r2);x2 = (-b - q) * (y0 * y0)/ (2 * r2);
y1 = k * (x1 + x0 / 2) - y0 / 2;y2 = k * (x2 + x0 / 2) - y0 / 2;
if(fabs(y1 - y2) <= eps){
if(x1 < x2){
printf("%.3lf %.3lf %.3lf %.3lf\n", x1, y1, x2, y2);
}
else{
printf("%.3lf %.3lf %.3lf %.3lf\n", x2, y2, x1, y1);
}
}
else if(y1 < y2){
printf("%.3lf %.3lf %.3lf %.3lf\n", x1, y1, x2, y2);
}
else{
printf("%.3lf %.3lf %.3lf %.3lf\n", x2, y2, x1, y1);
}
}
return 0;
}
ACMer
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
There are at least P% and at most Q% students of HDU are ACMers, now I want to know how many students HDU have at least?
Input
The input contains multiple test cases.
The first line has one integer,represent the number of test cases.
The following N lines each line contains two numbers P and Q(P < Q),which accurate up to 2 decimal places.
Output
For each test case, output the minumal number of students in HDU.
Sample Input
1 13.00 14.10
Sample Output
15
#include <iostream>
using namespace std;
const double eps = 1e-8;
int main()
{
double a, b;
int t;
cin >> t;
while(t--){
cin >> a >> b;
// a /= 100;
// b /= 100;
for(int i = 1; ; i++){
if( int( i * a / 100 ) < int( i * b / 100) ){
cout << i << endl;
break;
}
}
}
return 0;
}
ACboy needs your help again!
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
ACboy was kidnapped!!
he miss his mother very much and is very scare now.You can't image how dark the room he was put into is, so poor :(.
As a smart ACMer, you want to get ACboy out of the monster's labyrinth.But when you arrive at the gate of the maze, the monste say :" I have heard that you are very clever, but if can't solve my problems, you will die with ACboy."
The problems of the monster is shown on the wall:
Each problem's first line is a integer N(the number of commands), and a word "FIFO" or "FILO".(you are very happy because you know "FIFO" stands for "First In First Out", and "FILO" means "First In Last Out").
and the following N lines, each line is "IN M" or "OUT", (M represent a integer).
and the answer of a problem is a passowrd of a door, so if you want to rescue ACboy, answer the problem carefully!
Input
The input contains multiple test cases.
The first line has one integer,represent the number oftest cases.
And the input of each subproblem are described above.
Output
For each command "OUT", you should output a integer depend on the word is "FIFO" or "FILO", or a word "None" if you don't have any integer.
Sample Input
4 4 FIFO IN 1 IN 2 OUT OUT 4 FILO IN 1 IN 2 OUT OUT 5 FIFO IN 1 IN 2 OUT OUT OUT 5 FILO IN 1 IN 2 OUT IN 3 OUT
Sample Output
1 2 2 1 1 2 None 2 3
Source
2007省赛集训队练习赛(1)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <set>
#include <utility>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
#define N 10000
#define INF 100000000
queue<int> que;
int a[N], l = 0;
int n, m, num;
string s, d;
int main()
{
// freopen("date.txt", "r", stdin);
int t;
scanf("%d", &t);
while(t--){
cin >> n >> s;
l = 0;
while(!que.empty()){
que.pop();
}
if(s == "FIFO"){
for(int i = 1; i <= n; i++){
cin >> s;
if(s == "IN"){
cin >> num;
que.push(num);
}
else{
if(que.empty()){
cout << "None\n";
}
else{
cout << que.front() << endl;
que.pop();
}
}
}
}
else{
for(int i = 1; i <= n; i++){
cin >> s;
if(s == "IN"){
cin >> num;
a[l++] = num;
}
else{
if(l == 0){
cout << "None\n";
}
else{
cout << a[--l] << endl;
}
}
}
}
}
return 0;
}
PBD
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
PrisonBreak is a popular TV programme in HDU. ACboy likes it very much, and he join a PrisonBreak discussing team called "PBD".Every Tuesday night, a lot of PBDers will contact with each other to discuss the newest plot of PrisonBreak season2. Generally speaking, every PBDer has distinct ideas about the play, so everyone want to know all the others' ideas. For example, when ACboy contract with Sam, ACboy will tell all the ideas he konws to Sam, and Sam will also tell all the ideas he konws to ACboy, and the call costs 5 yuan.
If there are N people in the "PBD" team, what is the minimum cost to let everyone knows all the others' ideas?
Input
The input contains multiple test cases.
Each test case contains a number N, means there are N people in the "PBD" team.N = 0 ends the input.(A call cost 5 yuan).
Output
for each case, output a integer represent the minimum cost to let everyone knows all the others' ideas.
Sample Input
1 2 3 4 0
Sample Output
0 5 15 20HintIf there are 2 people, for example, named A, B. Then A calls B, then A and B will know each other's ideas, so it only needs one call, so the minimum cost is 1*5 = 5 yuan.
#include <iostream>
using namespace std;
int main()
{
int n;
while(cin >> n && n){
if(n == 1) cout << 0 << endl;
else if(n == 2) cout << 5 << endl;
else if(n == 3) cout << 15 << endl;
else if(n == 4) cout << 20 << endl;
else cout << 5 * ( 2 * (n - 4) + 4 ) << endl;
}
return 0;
}
Rank
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
there are N ACMers in HDU team.
ZJPCPC Sunny Cup 2007 is coming, and lcy want to select some excellent ACMers to attend the contest. There have been M matches since the last few days(No two ACMers will meet each other at two matches, means between two ACMers there will be at most one match). lcy also asks"Who is the winner between A and B?" But sometimes you can't answer lcy's query, for example, there are 3 people, named A, B, C.and 1 match was held between A and B, in the match A is the winner, then if lcy asks "Who is the winner between A and B", of course you can answer "A", but if lcy ask "Who is the winner between A and C", you can't tell him the answer.
As lcy's assistant, you want to know how many queries at most you can't tell lcy(ask A B, and ask B A is the same; and lcy won't ask the same question twice).
Input
The input contains multiple test cases.
The first line has one integer,represent the number of test cases.
Each case first contains two integers N and M(N , M <= 500), N is the number of ACMers in HDU team, and M is the number of matchs have been held.The following M lines, each line means a match and it contains two integers A and B, means A wins the match between A and B.And we define that if A wins B, and B wins C, then A wins C.
Output
For each test case, output a integer which represent the max possible number of queries that you can't tell lcy.
Sample Input
3 3 3 1 2 1 3 2 3 3 2 1 2 2 3 4 2 1 2 3 4
Sample Output
0 0 4Hintin the case3, if lcy ask (1 3 or 3 1) (1 4 or 4 1) (2 3 or 3 2) (2 4 or 4 2), then you can't tell him who is the winner.
Source
2007省赛集训队练习赛(1)
#include <bitset>
#include <cstdio>
#include <iostream>
using namespace std;
#define N 505
int main()
{
bitset<N> mp[N];
int t, a, b, n, m, cnt;
scanf("%d", &t);
while(t--){
for(int i = 0; i < N; i++)
mp[i].reset();
cnt = 0;
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){
scanf("%d%d", &a, &b);
mp[a][b] = true;
}
for(int k = 1; k <= n; k++){
for(int i = 1; i <= n; i++){
if(mp[i][k]){
mp[i] |= mp[k];
}
}
}
// for(int k = 1; k <= n; k++){
// for(int i = 1; i <= n; i++){
// cout << mp[k][i];
// }
//cout << endl;
//}
for(int i = 1; i <= n; i++){
for(int j = i + 1; j <= n; j++){
if(!mp[i][j] && !mp[j][i]){
cnt++;
}
}
}
printf("%d\n", cnt);
}
return 0;
}
/**
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define N 505
int main()
{
int t, a, b, n, m, ans;
bool maze[N][N];
scanf("%d", &t);
while(t--){
memset(maze, false, sizeof maze);
ans = 0;
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){
scanf("%d%d", &a, &b);
maze[a][b] = true;
}
for(int k = 1; k <= n; k++){
for(int i = 1; i <= n; i++){
if(maze[i][k]){
for(int j = 1; j <= n; j++){
if(maze[k][j])
maze[i][j] = true;
}
}
}
}
//for(int i = 1; i <= n; i++){
// for(int j = 1; j <= n; j++)
// cout << maze[i][j];
// cout << endl;
//}
for(int i = 1; i <= n; i++){
for(int j = i + 1; j <= n; j++){
if(!maze[i][j] && !maze[j][i]){
ans++;
}
}
}
printf("%d\n", ans);
}
return 0;
}
*/
最后两种判断方法,一种是 !mp[i][j] || mp[j][i] , 一种是!mp[i][j] && !mp[j][i],提交证明两种是等价的。
Count the grid
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
A lattice point is an ordered pair (x, y) where x and y are both integers. Given the coordinates of the vertices of a triangle (which happen to be lattice points), you are to count the number of lattice points which lie completely inside of the triangle (points on the edges or vertices of the triangle do not count).
Input
The input test file will contain multiple test cases. Each input test case consists of six integers x1, y1, x2, y2, x3, and y3, where (x1, y1), (x2, y2), and (x3, y3) are the coordinates of vertices of the triangle. All triangles in the input will be non-degenerate (will have positive area), and -15000 ≤ x1, y1, x2, y2, x3, y3 ≤ 15000. The end-of-file is marked by a test case with x1 = y1 = x2 = y2 = x3 = y3 = 0 and should not be processed.
Output
For each input case, the program should print the number of internal lattice points on a single line.
Sample Input
0 0 1 0 0 1 0 0 5 0 0 5 0 0 0 0 0 0
Sample Output
0 6
Source
2007省赛集训队练习赛(1)
套路,都是套路。皮条客定理。
///皮克定理:多边形面积=内部整数点数a+边上的整数点数b/2-1
///https://blog.csdn.net/baoli1008/article/details/38853869
#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b)
{
int tmp;
while(b){
tmp = b;
b = a % b;
a = tmp;
}
return a;
}
int main()
{
int x1, y1, x2, y2, x3, y3, s;
int a1, a2, b1, b2, c1, c2;
int cnt, ans;
while(scanf("%d%d%d%d%d%d", &x1, &y1, &x2, &y2, &x3, &y3) != EOF){
if(!x1 && !y1 && !x2 && !y2 && !x3 && !y3)
break;
cnt = 0;
///三边向量
a1 = x2 - x1;a2 = y2 - y1;
b1 = x3 - x1;b2 = y3 - y1;
c1 = x3 - x2;c2 = y3 - y2;
///叉积,面积的两倍
s = abs(a1 * b2 - b1 * a2);
///那个定理
cnt += gcd(abs(a1), abs(a2));
cnt += gcd(abs(b1), abs(b2));
cnt += gcd(abs(c1), abs(c2));
ans = (s - cnt + 2) / 2;
printf("%d\n", ans);
}
return 0;
}
大菲波数
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
Fibonacci数列,定义如下:
f(1)=f(2)=1
f(n)=f(n-1)+f(n-2) n>=3。
计算第n项Fibonacci数值。
Input
输入第一行为一个整数N,接下来N行为整数Pi(1<=Pi<=1000)。
Output
输出为N行,每行为对应的f(Pi)。
Sample Input
5 1 2 3 4 5
Sample Output
1 1 2 3 5
Source
2007省赛集训队练习赛(2)
高精度。
#include <bits/stdc++.h>
using namespace std;
#define N 1001
string num[N];
void highadd(const string & a, const string & b, int p)
{
int n[N] = {0}, m[N] = {0}, ans[N] = {0};
int la = a.length(), lb = b.length();
for(int i = 0; i < la; i++)
n[i] = a[la - i - 1] - '0';
for(int i = 0; i < lb; i++)
m[i] = b[lb - i - 1] - '0';
int x = 0, k = max(la, lb);
for(int i = 0; i < k; i++){
ans[i] = n[i] + m[i];
}
for(int i = 0; i < k; i++){
ans[i] += x;
x = ans[i] / 10;
ans[i] %= 10;
}
while(x){
ans[k] = x % 10;
x /= 10;
k++;
}
num[p].clear();
for(int i = k - 1; i >= 0; i--){
num[p] += char(ans[i] + '0');
}
}
int main()
{
num[1] = "1";
num[2] = "1";
for(int i = 3; i < N; i++){
highadd(num[i - 1], num[i - 2], i);
}
int t, n;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
cout << num[n] << endl;
}
return 0;
}
排列2
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
Ray又对数字的列产生了兴趣:
现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数。
Input
每组数据占一行,代表四张卡片上的数字(0<=数字<=9),如果四张卡片都是0,则输入结束。
Output
对每组卡片按从小到大的顺序输出所有能由这四张卡片组成的4位数,千位数字相同的在同一行,同一行中每个四位数间用空格分隔。
每组输出数据间空一行,最后一组数据后面没有空行。
Sample Input
1 2 3 4 1 1 2 3 0 1 2 3 0 0 0 0
Sample Output
1234 1243 1324 1342 1423 1432 2134 2143 2314 2341 2413 2431 3124 3142 3214 3241 3412 3421 4123 4132 4213 4231 4312 4321 1123 1132 1213 1231 1312 1321 2113 2131 2311 3112 3121 3211 1023 1032 1203 1230 1302 1320 2013 2031 2103 2130 2301 2310 3012 3021 3102 3120 3201 3210
Source
2007省赛集训队练习赛(2)
next-permutation直接弄就好了,但是这个输出的换行和空格就贼烦人。。。立了4个flag
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <set>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
#define N 10000
#define INF 100000000
int a[4];
char now;
map<string, bool> mp;
string s;
string tostring()
{
string s = "";
for(int i = 0; i < 4; i++){
s += char('0' + a[i]);
}
return s;
}
bool f1, f2, f3, f4;
int main()
{
// freopen("date.txt", "r", stdin);
f1 = f4 = false;
while(scanf("%d%d%d%d", &a[0], &a[1], &a[2], &a[3]) && a[0]+a[1]+a[2]+a[3]){
mp.clear();
f2 = f3 = false;
do{
s = tostring();
if(s[0] == '0')
continue;
if(mp[s]){
continue;
}
else{
if(!f2){
if(f4){
cout << '\n';
}
f2 = true;
now = s[0];
}
mp[s] = true;
if(s[0] == now){
if(f3){
cout << ' ';
}else{
f3 = true;
}
cout << s;
}
else{
cout << '\n' << s;
now = s[0];
}
}
}while(next_permutation(a, a + 4));
f4 = true;
cout << '\n';
}
return 0;
}
小数化分数2
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
Input
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
Output
对每一个对应的小数化成最简分数后输出,占一行。
Sample Input
3 0.(4) 0.5 0.32(692307)
Sample Output
4/9 1/2 17/52
Source
2007省赛集训队练习赛(2)
百度的算法,是乘乘整数再减去小数得到整数,模拟题。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b)
{
ll tmp;
while(b){
tmp = b;
b = a % b;
a = tmp;
}
return tmp;
}
ll power(ll a, ll b)
{
ll ans = 1;
while(b){
if(b & 1)
ans *= a;
a *= a;
b >>= 1;
}
return ans;
}
int main()
{
string s;
int t, ls;
bool flag;
cin >> t;
while(t--){
cin >> s;
ls = s.length();
if(s[2] == '('){
ll a = 0, b = 0;
for(int i = 3; i < ls - 1; i++){
b++;
a = a * 10 + s[i] - '0';
}
ll fenmu;
ll g = gcd(a, fenmu = power(10, b) - 1);
cout << a / g << '/' << fenmu / g << endl;
}
else{
flag = true;
for(int i = 2; i < ls; i++){
if(s[i] == '('){
flag = false;
break;
}
}
if(flag){
ll a = 0, b = 1;
for(int i = 2; i < ls; i++){
b *= 10;
a = a * 10 + s[i] - '0';
}
ll g = gcd(a, b);
a /= g;b /= g;
cout << a << '/' << b << endl;
}
else{
ll a = 0, la = 0, b = 0, lb = 0, c;
for(int i = 2; s[i] != '('; i++){
la++;
a = a * 10 + s[i] - '0';
}
c = a;
for(int i = 3 + la; s[i] != ')'; i++){
lb++;
b = b * 10 + s[i] - '0';
c = c * 10 + s[i] - '0';
}
ll fenzi = c - a;
ll fenmu = power(10, la + lb) - power(10, la);
ll g = gcd(fenzi, fenmu);
cout << fenzi / g << '/' << fenmu / g << endl;
}
}
}
return 0;
}
Rank
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
Jackson wants to know his rank in the class. The professor has posted a list of student numbers and marks. Compute Jackson’s rank in class; that is, if he has the top mark(or is tied for the top mark) his rank is 1; if he has the second best mark(or is tied) his rank is 2, and so on.
Input
The input consist of several test cases. Each case begins with the student number of Jackson, an integer between 10000000 and 99999999. Following the student number are several lines, each containing a student number between 10000000 and 99999999 and a mark between 0 and 100. A line with a student number and mark of 0 terminates each test case. There are no more than 1000 students in the class, and each has a unique student number.
Output
For each test case, output a line giving Jackson’s rank in the class.
Sample Input
20070101 20070102 100 20070101 33 20070103 22 20070106 33 0 0
Sample Output
2
Source
2007省赛集训队练习赛(2)
#include <bits/stdc++.h>
using namespace std;
struct node{
string s;
int mak;
bool operator < (const node & a) const{
return mak > a.mak;
}
};
priority_queue< node, vector<node> > que;
int rak, mak;
string id;
node tmp;
int main()
{
while(cin >> id){
while(!que.empty()) que.pop();
while(cin >> tmp.s >> tmp.mak){
if(tmp.s == "0" && tmp.mak == 0)
break;
que.push(tmp);
}
rak = 0;
while(!que.empty()){
rak++;
tmp = que.top();que.pop();
if(tmp.s == id){
break;
}
}
cout << rak << endl;
while(!que.empty()) que.pop();
}
return 0;
}
水题,我用优先队列直接写的。
#include <bits/stdc++.h>
using namespace std;
struct node{
string s;
int mak;
bool operator < (const node & a) const{
return mak > a.mak;
}
};
priority_queue< node, vector<node> > que;
int rak, mak;
string id;
node tmp;
int main()
{
while(cin >> id){
while(!que.empty()) que.pop();
while(cin >> tmp.s >> tmp.mak){
if(tmp.s == "0" && tmp.mak == 0)
break;
que.push(tmp);
}
rak = 0;
while(!que.empty()){
rak++;
tmp = que.top();que.pop();
if(tmp.s == id){
break;
}
}
cout << rak << endl;
while(!que.empty()) que.pop();
}
return 0;
}
Friend
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
Friend number are defined recursively as follows.
(1) numbers 1 and 2 are friend number;
(2) if a and b are friend numbers, so is ab+a+b;
(3) only the numbers defined in (1) and (2) are friend number.
Now your task is to judge whether an integer is a friend number.
Input
There are several lines in input, each line has a nunnegative integer a, 0<=a<=2^30.
Output
For the number a on each line of the input, if a is a friend number, output “YES!”, otherwise output “NO!”.
Sample Input
3 13121 12131
Sample Output
YES! YES! NO!
Source
2007省赛集训队练习赛(2)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll quit(ll n, ll m)
{
while(n % m == 0){
n /= m;
}
return n;
}
int main()
{
ll n;
while(scanf("%lld", &n) != EOF){
if(n == 0){
printf("NO!\n");
continue;
}
++n;
n = quit(n, 3);
n = quit(n, 2);
if(n == 1){
printf("YES!\n");
}
else{
printf("NO!\n");
}
}
return 0;
}
The diameter of graph
Time Limit: 1000 ms /Memory Limit: 32768 kb
Description
The graph diameter is the length of the "longest shortest path" between any two vertices of a graph. In other words, a graph's diameter is the longest path which must be traversed in order to travel from any vertex to another when paths which backtrack, detour, or loop are excluded from consideration.
Given an undirected graph, your mission is to count the number of diameters of it.
Input
The input contains multiple test cases.
For each test case, it contains n+1 lines.
Line 1: two integers m, n (2<= m <= 100, 1 <= n <= 4000) indicating that there are m vertices and n edges in the city.
Line 2~n+1: each contains three integers i, j, d (1 <= i, j <= m, 1 <= d <= 100), indicating that there is an edge of length d connecting vertex i and vertex j.
Output
Output the value of the diameter and the number of diameters in a single line, separated by a single space.
Sample Input
4 5 1 2 1 2 3 1 3 4 1 1 4 1 1 3 2
Sample Output
2 5
Source
2007省赛集训队练习赛(1)
#include <cstdio>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <set>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
#define N 102
#define INF 0x3f3f3f3f
int val, dp[N][N];
int n, m, a, b, c, ans;
int cnt[N][N];
int main()
{
// freopen("data.txt", "r", stdin);
while(scanf("%d%d", &n, &m) != EOF){
memset(dp, 0x3f, sizeof dp);
memset(cnt, 0, sizeof cnt);
for(int i = 0; i < m; i++){
scanf("%d%d%d", &a, &b, &c);
if(a == b)
continue;
if(dp[a][b] > c){
dp[a][b] = dp[b][a] = c;
cnt[a][b] = cnt[b][a] = 1;
}
else if(dp[a][b] == c){//重边
++cnt[a][b];++cnt[b][a];
}
}
for(int k = 1; k <= n; k++){
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(dp[i][k] + dp[k][j] < dp[i][j]){
dp[i][j] = dp[i][k] + dp[k][j];
///笛卡尔积
cnt[i][j] = cnt[i][k] * cnt[k][j];
}
else if(dp[i][j] == dp[i][k] + dp[k][j]){
cnt[i][j] += cnt[i][k] * cnt[k][j];
}
}
}
}
val = -1;
ans = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(val < dp[i][j]){
val = dp[i][j];
}
}
}
for(int i = 1; i <= n; i++){
for(int j = 1 + i; j <= n; j++){
if(dp[i][j] == val){
ans += cnt[i][j];
}
}
}
printf("%d %d\n", val, ans);
}
return 0;
}