1. 求一个有向图所有顶点入度的和
输入有向图的顶点个数,边数以及各顶点之间的关联情况,要求求出这个有向图的所有顶点入度的总和。
【输入格式】
第1行:2个空格分开的整数n(2<=n<=200)和m(10<=m<=20000),分别表示图的顶点和边数。
第2至m+1行:每行2个空格分开的整数i,j,i表示一条边的起点,j表示终点。
【输出格式】
只有1行,为1个整数,表示所有顶点的入度总和。
【样例输入】
3 6
1 2
1 3
2 1
2 3
3 1
3 2
【样例输出】
6
#include <iostream> using namespace std; int a[201][201],n,m,ans = 0; void init() { int i,j,k; cin >> n >> m; for(i=1;i<=m;i++) { cin >> j >> k; a[j][k] = 1; } } int main() { init(); for(int i = 1;i <= n; i++){ for(int j = 1;j <= n;j++){ if(a[j][i] == 1){ ans++; } } } cout << ans << endl; }
2、同班同学
有一个学校拥有N位学生,有些学生彼此是同班同学。我们根据“我的同班同学的同班同学也是我的同班同学”;也就是,如果A和B是同班同学,而且B和C是同班同学,那么A和C也是同班同学;换言之,A、B、C都是同一班的学生。当输入所有学生之间的这种关系后,计算全校共有几个班级?
【输入格式】
第1行,输入N和M,N为学生个数,M为有同班关系的同学的对数,(0<=N<=1000,0<=M<=100)接下来M行,输入有同班关系的学生编号。
【输出格式】
共1行,全校班级的个数
【样例输入】
6 5
1 2
3 4
4 5
4 6
5 6
【样例输出】
2
#include<iostream> using namespace std; int g[1001][1001],visited[1001]; int sum = 0,n,m; int total = 0; void dfs(int cur){ visited[cur] = 1; sum++; if(sum==n) return; for(int i=1;i<=n;i++){ if(g[cur][i]==1&&visited[i]!=1){ visited[i]=1; dfs(i); } } } int main(){ cin>>n>>m; int i,j,a,b; for(i=1;i<=m;i++){ cin>>a>>b; g[a][b]=1; g[b][a]=1; } for(i = 1;i <= n;i++){ if(visited[i] != 1){ dfs(i); total += 1; } } cout << total << endl; return 0; }
1、铲雪车
随着白天越来越短夜晚越来越长,我们不得不考虑铲雪问题了。整个城市所有的道路都是双车道,因为城市预算的削减,整个城市只有1辆铲雪车。铲雪车只能把它开过的地方(车道)的雪铲干净,无论哪儿有雪,铲雪车都得从停放的地方出发,游历整个城市的街道。现在的问题是:最少要花多少时间去铲掉所有道路上的雪呢?
【输入格式】
输入数据的第1行表示铲雪车的停放坐标(x,y),x,y为整数,单位为米。
第2行表示街道的数量n(n<100),接下来n行,每行给出了一条街道的起点坐标和终点坐标,所有街道都是笔直的,且都是双向一个车道。铲雪车可以在任意交叉口、或任何街道的末尾任意转向,包括转U型弯。铲雪车铲雪时前进速度为20 km/h,不铲雪时前进速度为50 km/h。
保证:铲雪车从起点一定可以到达任何街道。
【输出格式】
铲掉所有街道上的雪并且返回出发点的最短时间,精确到分钟。
【样例输入】
0 0
3
0 0 10000 10000
5000 -10000 5000 10000
5000 10000 10000 10000
【样例输出】
3:55
【注释】
3小时55分钟
#include<iostream> #include<cstdio> #include<cmath> using namespace std; double fun(int a,int b,int c,int d) { double x,y; x = abs(a - c); y = abs(b - d); return sqrt(x * x + y * y) / 10000; } int main(){ int x, y; while(cin >> x >> y) { int n, x1, y1, x2, y2; double sum = 0; cin >> n; for(int i = 1; i <= n; i ++) { cin >> x1 >> y1 >> x2 >> y2; sum += fun(x1,y1,x2,y2); } int T = sum - 1; double t = sum - T; int te = floor(t * 60 + 0.5); if(te >= 60) { T ++; te -= 60; } cout << T << ":"; if(te < 10) cout << "0"; cout << te << endl; } return 0; }
2.骑马修栅栏
农民John每年有很多栅栏要修理。他总是骑着马穿过每一个栅栏并修复它破损的地方。
John是一个懒惰的人,他讨厌骑马,因此从来不两次经过同一个栅栏。现在你编写一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每一个栅栏恰好都经过一次。John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。
每个栅栏连接两个顶点,顶点用1到500标号(虽然有的农场并没有500个顶点)。一个顶点上可连接任意多(>=1)个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。
你的程序必须输出骑马的路径(用路上依次经过的顶点号码表示)。我们如果把输出的路径看成一个500进制的数,那么当存在多组解的情况下,输出500进制表示法中最小的一个(也就是输出第一个较小的数,如果还有多组解,输出第二个较小的数,等等)。输出数据保证至少有一个解。
【输入格式】
第1行:一个整数F(1<=F<=1024),表示栅栏的数目。
第2到F+1行:每行两个整数i,j(1<=i , j<=500)表示这条栅栏连接i与j号顶点。
【输出格式】
输出应当有F+1行,每行一个整数,依次表示路径经过的顶点号。注意数据可能有多组解,但是只有上面题目要求的那一组解释正确的。
【样例输入】
9
1 2
2 3
3 4
4 2
4 5
2 5
5 6
5 7
4 6
【样例输出】
1
2
3
4
2
5
4
6
5
7
#include <iostream> #include <cstring> using namespace std; int g[2001][2001]; int du[2001]; int circuit[2001]; int n,m,tot,x,y,start; void find(int i){ for(int j = 1;j <= n;j++) if(g[i][j]){ g[i][j]--; g[j][i]--; find(j); } circuit[++tot] = i; } int main(){ memset(g,0,sizeof(g)); cin >> m; for(int i = 1;i <= m;i++){ cin >> x >> y; g[x][y]++; g[y][x]++; du[x]++; du[y]++; n = max(n,max(x,y)); } start = 1; for(int i =1;i <= n;i++) if(du[i] % 2){ start = i; break; } tot = 0; find(start); for(int i = tot;i >= 1;i--) cout << circuit[i] << endl; return 0; }