图论OJ
A.最小生成树 |
Time Limit: 1000 MSMemory Limit: 32768 KTotal Submit: 14 |
(6 users)Total Accepted: 6 (5 users)Special Judge: No |
Description |
根据输入构建无向带权图,并利用kruskal法求出最小生成树,输出该 |
最小生成树的各边权值和。 |
Input |
输入第一行为:结点数和边(或弧)的数目; 第二行为各结点名;第 |
三行为各边的权值。输出为:最小生成树的各边权值和。 |
Sample Input |
5 7 |
A B C D E |
A B 10 |
A C 8 |
A E 3 |
B C 2 |
B D 5 |
C E 7 |
D E 4 |
Sample Output |
14 |
Hint |
输出有换行符。 |
#include<iostream>
#include<algorithm>
#include<math.h>
#include<cstdio>
int mark[100];
using namespace std;
typedef struct node
{
int ii, jj;
int cost;
}Node;
bool cmp(Node x,Node y)
{
return x.cost< y.cost;
}
int Comproot(int x) {
if (x == mark[x])
return x;
else
return Comproot(mark[x]);
}
int main()
{
int v, e;
char ss[100];
Node node[100];
for (int i = 0; i < 100; i++)
{
mark[i] = i;
}
cin >> v >> e;
for(int i = 0; i < v; i ++){
cin>>ss[i];
}
char aa,bb;
for (int i = 0; i < e; i++)
{
cin>>aa>>bb>>node[i].cost;
for(int j = 0; j < 100; j++){
if(ss[j] == aa){
node[i].ii = j+1;
}
if(ss[j] == bb){
node[i].jj = j+1;
}
}
}
sort(node, node + e, cmp);
int sum = 0;
for (int i = 0; i < e; i++)
{
int a = Comproot(node[i].ii);
int b = Comproot(node[i].jj);
if (a == b)
continue;
mark[a] = b;
sum = sum + node[i].cost;
}
cout << sum<<endl;
return 0;
}
B.图的广度优先搜索 |
Time Limit: 1000 MSMemory Limit: 32768 KTotal Submit: 15 |
(6 users)Total Accepted: 6 (6 users)Special Judge: No |
Description |
根据输入建立无向图,利用邻接表法对该图进行广度优先搜索,并输 |
出遍历序列。 |
Input |
说明:输入第一行为结点数和边(或弧)的数目;第二行为结点的值; |
第三行值最后为该图的弧(边);默认广度优先遍历从第一个结点出发。 |
Output |
输出为广度优先遍历序列。 |
Sample Input |
5 5 |
A B C D E |
A B |
B C |
B E |
C D |
D E |
Sample Output |
A B C E D |
Hint |
输出有换行符 |
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
int* g_visited;
int* g_queue;
int g_front = -1, g_rear = -1;
int g_queue_size;
int g_vernum;
int g_arcnum;
typedef struct VNode //头结点的类型定义
{
char data[100];
int nextver_index;
struct VNode* nextver_point;
}AdjList;
typedef struct //图的类型定义
{
AdjList* vertex;
int* arcs;
int vernum, arcnum;
}MGraph;
void Visited_init(MGraph* N)
{
int v;
for (v = 0; v < g_vernum; v++)
{
g_visited[v] = 0;
}
return;
}
void CreateGraph_T(MGraph* N)
{
int i, j, k;
char aa, bb;
memset((char*)N->arcs, 0, 4 * g_vernum * g_vernum);
for (i = 0; i < g_vernum; i++)
{
cin >> N->vertex[i].data;
}
for (k = 0; k < g_arcnum;)
{
cin >> aa >> bb;
for (int t = 0; t < g_vernum; t++) {
if (N->vertex[t].data[0] == aa) {
i = t;
}
if (N->vertex[t].data[0] == bb) {
j = t;
}
}
if (i >= g_vernum || j >= g_vernum)
{
printf("第 %d 条边的两个顶点序号(逗号隔开): 输入错误,请重新输入\t\n\n", k + 1);
continue;
}
N->arcs[i * g_vernum + j] = 1;
N->arcs[j * g_vernum + i] = 1;
k++;
}
}
void Visit1(char* v)
{
printf(" %s", v);
}
void Visit(char* v)
{
printf("%s", v);
}
int Visited_set(int key)
{
g_visited[key] = 1;
return 0;
}
int Visited_get(int key)
{
return g_visited[key];
}
int Enqueue(int key)
{
g_rear++;
g_queue[g_rear % g_queue_size] = key;
return 0;
}
int Dequeue(void)
{
g_front++;
return g_queue[g_front % g_queue_size];
}
int Queue_empty()
{
return g_front == g_rear;
}
int Queue_full()
{
return (g_rear - g_front) == g_queue_size;
}
void Queue_init()
{
g_front = -1;
g_rear = -1;
}
void BFS_T(MGraph* N)
{
int j;
int t = 0;
while (!Queue_empty() && !Queue_full())
{
t = Dequeue();
for (j = 1; j < g_vernum; j++)
{
if (N->arcs[t * g_vernum + j] == 1)
{
if (Visited_get(j) == 0)
{
Visited_set(j);
Visit1(N->vertex[j].data);
Enqueue(j);
}
}
}
}
}
void BFSTraverse_T(MGraph* N)
{
int v;
Visited_init(N);
Queue_init();
for (v = 0; v < g_vernum; v++)
{
if (Visited_get(v) == 1)
{
continue;
}
Visited_set(v);
Visit(N->vertex[v].data);
Enqueue(v);
BFS_T(N);
}
cout << endl;
}
int GraphInit(MGraph* N)
{
g_queue_size = g_vernum * g_vernum;
N->vertex = (AdjList*)malloc(sizeof(AdjList) * g_vernum);
N->arcs = (int*)malloc(sizeof(int) * g_vernum * g_vernum);
g_visited = (int*)malloc(sizeof(int) * g_vernum);
g_queue = (int*)malloc(sizeof(int) * g_queue_size);
if (N->vertex == NULL || N->arcs == NULL
|| g_visited == NULL || g_queue == NULL)
{
return -1;
}
return 0;
}
int GraphRelease(MGraph* N)
{
#ifdef GRAPH_LIST
int i;
AdjList* p;
AdjList* t;
for (i = 0; i < g_vernum; i++)
{
printf("%s[%d]", N->vertex[i].data, i);
p = N->vertex[i].nextver_point;
while (p != &N->vertex[i])
{
t = p;
p = p->nextver_point;
free(t);
}
}
#endif
free(N->arcs);
free(g_visited);
free(g_queue);
free(N->vertex);
return 0;
}
int main()
{
int ret;
MGraph N;
again:
cin >> g_vernum;
cin >> g_arcnum;
if (g_vernum == 0 || g_arcnum == 0)
{
goto again;
}
ret = GraphInit(&N);
if (ret == -1)
{
printf("程序初始化失败\n");
return 0;
}
#ifdef GRAPH_LIST
printf("邻接表链表结构\n");
CreateGraph_L(&N);
DisplayGraph_L(&N);
BFSTraverse_L(&N);
DFSTraverse_L(&N);
#endif
CreateGraph_T(&N);
BFSTraverse_T(&N);
GraphRelease(&N);
exit(0);
return 0;
}
C.最短路径 |
Time Limit: 1000 MSMemory Limit: 32768 KTotal Submit: 15 |
(6 users)Total Accepted: 6 (6 users)Special Judge: No |
Description |
题目内容:有n个村庄,现要选择在一个村庄中建立一所医院,使得该 |
医院到离其最远的村庄,距离最近。根据输入建立无向带权图,并利用 |
最短路径算法实现。 |
Input |
输入第一行为村庄数和路径的数目;第二行为各村庄名;第三行至最 |
后为各村庄的距离。 |
Output |
所选医院所在的村庄。 |
Sample Input |
4 5 |
A B C D |
A B 8 |
A D 6 |
B C 4 |
B D 5 |
C D 3 |
Sample Output |
D |
Hint |
输出有换行符 |
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#define MAX 32767
int N = 0;
using namespace std;
typedef struct AM_Graph//图的邻接矩阵类型
{
int AdjMatrix[100][100];
int VexNum,ArcNum;
char VexName[100];
} AM_Graph;
void Floyd(AM_Graph g,int Dist[100][100])
{
int i,j,k;
int count=0;
for(i=0; i<N; i++)
for(j=0; j<N; j++)
{
if((Dist[i][j]!=0)&&(Dist[i][j]!=MAX))
count++;
g.AdjMatrix[i][j]=Dist[i][j];
}
g.VexNum=N;
g.ArcNum=count;
for(k=0; k<N; k++)
{
for(i=0; i<N; i++)
{
for(j=0; j<N; j++)
{
if(Dist[i][j]>(Dist[i][k]+Dist[k][j]))
{
Dist[i][j]=Dist[i][k]+Dist[k][j];
}
}
}
}
}
void BuildEc(int Dist[100][100],int Ec[100])
{
int i,j;
int temp;
for(i=0; i<N; i++)
{
temp=Dist[0][i];
for(j=0; j<N; j++)
{
if(temp<Dist[j][i])
temp=Dist[j][i];
}
Ec[i]=temp;
}
}
int minEc(int Ec[100])
{
int i,temp,k;
k=0;
for(i=1; i<N; i++)
{
temp=Ec[k];
if(temp>Ec[i])
{
k=i;
}
}
return k;
}
void print(int Dist[100][100],int Ec[100],char VexName[100])
{
int k;
k=minEc(Ec);
printf("%c\n",VexName[k]);
}
int main()
{
int i,j;
int x,y;
int dist[100][100];
memset(dist,-1,sizeof(dist));
int EC[100];
AM_Graph g;
int n,v;
cin>>N>>v;
char aa,bb;
for(i=0; i<N; i++)
cin>>g.VexName[i];
for(int j = 0; j < v; j ++)
{
cin>>aa>>bb;
for(int t= 0; t < N; t++)
{
if(g.VexName[t] == aa)
{
x = t;
}
if(g.VexName[t] == bb)
{
y = t;
}
}
scanf("%d",&dist[x][y]);
dist[y][x] = dist[x][y];
}
for(i=0; i<N; i++)
{
dist[i][i]=0;
for(j=0; j<N; j++)
{
if(dist[i][j]<0)
dist[i][j]=MAX;
}
}
Floyd(g,dist);
BuildEc(dist,EC);
print(dist,EC,g.VexName);
return 0;
}
D.AOE网的关键路径 |
Time Limit: 1000 MSMemory Limit: 32768 KTotal Submit: 3 |
(3 users)Total Accepted: 3 (3 users)Special Judge: No |
Description |
题目内容:对一个工程网,计算完成工程的最短工期。根据输入建立有 |
向带权图,并验证有向无环图,利用拓扑排序,求出关键路径,计算工期。 |
Input |
输入第一行为结点数和边(或弧)的数目;第二行为各结点名称;第三 |
行至最后为带权的有向边。 |
Output |
输出为:关键路径的关键活动权值和,即该工程的最短工期。 |
Sample Input |
9 12 |
A B C D E F G H M |
A B 3 |
A C 10 |
B D 9 |
B E 13 |
C E 12 |
C F 7 |
D G 8 |
D H 4 |
E H 6 |
F H 11 |
G M 2 |
H M 5 |
Sample Output |
33 |
Hint |
输出有换行符 |
#include<iostream>
using namespace std;
#define pointMax 100
struct VtNode //权值信息
{
VtNode *nextVt;
int peace;
VtNode *nextVtt;
int peaceE;
int len;
};
struct PoNode //顶点信息
{
char data;
VtNode *firstPo;
VtNode *Out;
};
struct ATgroup
{
PoNode vertices[pointMax];
int point, vert;
};
struct Node
{
int data;
Node *next;
};
struct SqStack //栈
{
Node *base;
Node *top;
int data;
};
void Push(SqStack &S, int i)
{
Node *m = new Node;
m->data = i;
m->next = S.top;
S.top = m;
}
int Pop(SqStack &S)
{
int n = S.top->data;
S.top = S.top->next;
return n;
}
int ATlocate(ATgroup A, char x)
{
for (int i = 0; i < A.point; i++)
{
if (A.vertices[i].data == x)
{
return i;
}
}
}
void show(ATgroup &A)
{
for (int i = 0; i < A.point; i++)
{
if (A.vertices[i].firstPo != NULL)
{
}
if (A.vertices[i].Out != NULL)
{
}
}
}
void CreatAT(ATgroup &A)
{
cin >> A.point;
cin >> A.vert;
getchar();
char q[100];
for(int i = 0; i < A.point;i ++){
cin>>q[i];
}
for (int i = 0; i < A.point; i++)
{
A.vertices[i].data = q[i];
A.vertices[i].firstPo = NULL;
A.vertices[i].Out = NULL;
}
char v1, v2; int m, n; int len;
for (int i = 0; i < A.vert; i++)
{
int Q;
cin >> v1 >> v2 >> Q;
m = ATlocate(A, v1);
n = ATlocate(A, v2);
VtNode *p1 = new VtNode;
VtNode *p2 = new VtNode;
p1->peace = m;
p1->nextVt = A.vertices[n].firstPo;
A.vertices[n].firstPo = p1;
p2->peaceE = n;
p2->nextVtt = A.vertices[m].Out;
p2->len = Q;
A.vertices[m].Out = p2;
}
}
void FindIn(ATgroup *A, int *in)
{
int n = 0;
for (int i = 0; i < A->point; i++)
{
VtNode *p = new VtNode;
p = A->vertices[i].firstPo;
while (p != NULL)
{
n++;
p = p->nextVt;
}
in[i] = n;
n = 0;
}
}
void SHOW(int *a, ATgroup *A)
{
for (int i = 0; i < A->point; i++)
{
}
}
int M[pointMax] = { 0 };
int topo[pointMax];
void TPsort(ATgroup *A, SqStack &S)
{
int Indegree[pointMax];
FindIn(A, Indegree);
for (int i = 0; i < A->point; i++)
{
if (Indegree[i] == 0)
{
Push(S, i);
}
}
int m = 0;
int n, k;
while (S.base != S.top)
{
n = Pop(S);
topo[m] = n;
m++;
VtNode* p = new VtNode;
p = A->vertices[n].Out;
while (p != NULL)
{
k = p->peaceE;
Indegree[k]--;
if (Indegree[k] == 0)
{
Push(S, k);
}
p = p->nextVtt;
}
}
}
int ve[pointMax];
int vl[pointMax];
void CritPath(ATgroup *A)
{
int n = A->point;
for (int i = 0; i < n; i++)
ve[i] = 0;
int k, j;
for (int i = 0; i < n; i++)
{
k = topo[i];
VtNode *p = A->vertices[k].Out;
while (p != NULL)
{
j = p->peaceE;
if (ve[j] < ve[k] + p->len)
{
ve[j] = ve[k] + p->len;
}
p = p->nextVtt;
}
}
cout << ve[n-1] << endl;
for (int i = 0; i < n; i++)
{
vl[i] = ve[topo[n - 1]];
}
for (int i = n - 1; i >= 0; i--)
{
k = topo[i];
VtNode *p = A->vertices[k].Out;
while (p != NULL)
{
j = p->peaceE;
if (vl[k] > vl[j] - p->len)
{
vl[k] = vl[j] - p->len;
}
p = p->nextVtt;
}
}
int e, l;
for (int i = 0; i < n; i++)
{
VtNode *p = A->vertices[i].Out;
while (p != NULL)
{
j = p->peaceE;
e = ve[i];
l = vl[j] - p->len;
p = p->nextVtt;
}
}
}
int main()
{
ATgroup *A = new ATgroup;
SqStack *S = new SqStack;
S->top = S->base;
S->data = pointMax;
CreatAT(*A);
TPsort(A, *S);
CritPath(A);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!