今天再次巩固图的知识,自己手敲图结构,对其最短路径和最小二叉树代码进一步深入了解。
最小二叉树是计算遍整个图的最小总权值
最短路径是计算某个结点到另一个结点的最短路径
今天写的一个题目勒要用到翻转邻接矩阵,具体思路就是要枚举出这个点到所有顶点的路径距离,再进行比较看哪个最小。
//P1629 邮递员送信
#include <stdio.h>
int a[1001][1001];
int dis[1001], book1[1001];//book1,book2用来标记;
int book2[1001];
int main()
{
int n, m, u, v, w, i, t, j, inf = 99999999, sum = 0, min, tt;
scanf("%d%d", &n, &m);//输入数据
for (i = 1; i <= n; i++)//建图
for (j = 1; j <= n; j++)
if (i == j) a[i][j] = 0;
else a[i][j] = inf;
for (i = 1; i <= m; i++)
{
scanf("%d%d%d", &u, &v, &w);
if (a[u][v] > w)//注意这里,数据有重边的
a[u][v] = w;
}
for (i = 1; i <= n; i++)//初始化dis数组
dis[i] = a[1][i];
book1[1] = 1;//标记起点
//核心,Dijkstra算法
for (i = 1; i <= n - 1; i++)//送信
{
min = inf;
for (j = 1; j <= n; j++)
{
if (min > dis[j] && book1[j] == 0)//找出距离起点最近的点
{
min = dis[j];
t = j;
}
}
book1[t] = 1;//标记这个点
for (j = 1; j <= n; j++)//寻找距离t点最近的点
{
if (a[t][j] < inf)
if (dis[j] > dis[t] + a[t][j])
{
dis[j] = dis[t] + a[t][j];
}
}
}
for (i = 1; i <= n; i++)
if (dis[i] != inf) sum += dis[i];//将送信所用时间加起来
book2[1] = 1;//再次执行Dijkstra算法,回邮局
for (i = 1; i <= n; i++)//先将图翻转
for (j = 1; j < i; j++)
{
tt = a[i][j];
a[i][j] = a[j][i];
a[j][i] = tt;
}
for (i = 1; i <= n; i++)//数据初始化
dis[i] = a[1][i];
for (i = 1; i <= n - 1; i++)
{
min = inf;
for (j = 1; j <= n; j++)
{
if (min > dis[j] && book2[j] == 0)
{
min = dis[j];
t = j;
}
}
book2[t] = 1;
for (j = 1; j <= n; j++)
{
if (a[t][j] < inf)
if (dis[j] > dis[t] + a[t][j])
dis[j] = dis[t] + a[t][j];
}
}
for (i = 1; i <= n; i++)
if (dis[i] != inf) sum += dis[i];//把回邮局用的时间加起来
printf("%d\n", sum);
return 0;
}
今天测试写的几个题目
//P1421 小玉买文具
#include<stdio.h>
int main() {
int a, b;
scanf("%d %d", &a, &b);
int sum = a * 10 + b;
int result = sum / 19;
printf("%d", result);
return 0;
}
//P1060 [NOIP2006 普及组] 开心的金明
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
int main() {
int n, m;
scanf("%d %d", &n, &m);
int* v = (int*)malloc(sizeof(int) * m);
int* p = (int*)malloc(sizeof(int) * m);
for (int i = 0; i < m; i++) {
scanf("%d %d", &v[i], &p[i]);
}
int* dp = (int*)malloc(sizeof(int) * n);
memset(dp, 0, sizeof(int));
for(int i=0;i<m;i++)
for (int j = n; j >= v[i]; j--) {
dp[j] = fmax(dp[j], dp[j - v[i]] + v[i] * p[i]);
}
printf("%d", dp[n]);
return 0;
}
P1109 学生分组
#include<math.h>
#include<stdio.h>
int main() {
int n;
scanf("%d", &n);
int a[55];
int sum = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
sum += a[i];
}
int r, l;
scanf("%d %d", &l, &r);
int plus = 0;
int lose = 0;
for (int i = 0; i < n; i++) {
if (a[i] > r)
plus += a[i] - r;
if (a[i] < l)
lose += l - a[i];
}
if (sum < l * n)
printf("-1");
else if (sum > r * n)
printf("-1");
else {
if (plus > lose)
printf("%d", plus);
else
printf("%d", lose);
}
return 0;
}
//P2708 硬币翻转
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
char s[1001];
long long ans = 0;
gets(s);
for (int i = 0; s[i + 1] != "\0"; i++) {
if (s[i] != s[i + 1])
ans++;
}
if (s[strlen(s) - 1] == '0')
ans++;
printf("%ld", ans);
return 0;
}
//B3849 [GESP样题 三级] 进制转换
#include <stdio.h>
int x, r, s;
int a[1005];
void dfs(int num, int step) {
if (num < r) {
a[step] = num;
s = step;
return;
}
int i = num % r;
a[step] = i;
int j = num / r;
dfs(j, step + 1);
}
int main() {
scanf("%d %d", &x, &r);
dfs(x, 1);
for (int i = s; i >= 1; i--) {
if (a[i] <= 9) {
printf("%c", a[i] + '0');
}
else {
printf("%c", a[i] + 'A' - 10);
}
}
return 0;
}