acm, 기본 그래 픽 알고리즘 및 해석
전제 가 된 BFS 알고리즘 은 전체 그림 을 명시 적 으로 구축 하지 않 고 이웃 을 찾 을 때마다 도착 하거나 방문 이 끝나 면 종료 할 수 있다 는 장점 이 있 습 니 다.일반적으로 최 단 로 만 구 하 는 데 쓰 인 다.
기술: 배열 을 설정 하여 각 점 의 전구 점 을 기록 합 니 다.
그러나 DFS 로 서 는 전체 그림 을 명시 적 으로 구축 해 야 한다. 되 돌 릴 때 는 이전 지점 이나 다른 방식 으로 도착 하기 때문이다.실행 가능 한 경로 의 총 수 를 구 하 는 데 사용 합 니 다.
기교: 강력 한 가지치기.....
--------------------------------------------------------------------------------------------------------------------------------------------------
prim
알고리즘 핵심 사상: 집합 론의 관점 에서 볼 때 이 나무 에서 가장 가 까 운 점 을 계속 귀 약 하 는 것 이다.
weight[n] 이 집합 에서 각 점 (i) 까지 의 최 단 거 리 를 기록 합 니 다.
adjex[n] 이 집합 에서 어느 점 에서 각 점 (i) 까지 의 최 단 거 리 를 기록 합 니까?
visit[n] 어떤 점 이 그 집합 에 속 하 는 지 기록 하 라.
#include
#include
#define N 401
int state[N][N];
int maps [N][N];
int solve(int n)
{
int weight[N];
int adjex[N];
int visit[N];
int i,j,k;
int minnum,ans;
ans=0;
for(i=0;iweight[j] && visit[j] == 0)
minnum=weight[j],k=j;
visit[k]=1;
ans+=minnum;
for(j=1;j
Kruskal
핵심 사상: 가장 짧 은 변 으로 생 성 나 무 를 구축 하고 회 로 를 피한다.
집합 을 사용 하여 한 변 의 두 점 이 같은 집합 에 있 는 지 빠르게 조회 하여 회 로 를 피한다.
/*
,
*/
void kruskal (edgeset ge, int n, int e)
// ge
{
int set[MAXE], v1, v2, i, j;
for (i=1;i<=n;i++)
set[i]=0; // set
i=1; // i , 1
j=1; // j ge , 1
while (j
주: 그리고 집합 을 찾 으 면 경 로 를 압축 하여 조회 할 때마다 되 돌려 주 고 조회 시간 을 O (1) 로 돌려 줍 니 다.
Dijkstra
매번 그림 의 노드 로 모든 경 로 를 업데이트 하여 최 단 경로 의 목적 을 달성 합 니 다.
1. n 회 반복
2. 그래서 d [] 노드 에서 최소 x 찾기
3. 이 점 x 표시
4. 이 지점 에서 출발 하여 d [y] = min {d [y], d [x] + w [x] [y]} 을 업데이트 합 니 다.
void Dijkstra(){
int k;
for(int i=1;i<=n;i++)
dis[i] = map[1][i];
for(int i=1;i dis[j] ){
tmin = dis[j];
k = j;
}
used[k] = 1;
for(int j=1;j<=n;j++)
if( !used[j] &&dis[k] + map[k][j] < dis[j] ) // ,
dis[j] = dis[k] + map[k][j];
}
printf("%d",dis[n]);
} /* 1 N ,dis[i] i By Ping*/
// , ,
Floyd
업 데 이 트 된 중간 노드 k 를 사용 하여 가장 바깥쪽 에 있 습 니 다.(맨 안쪽 에 방법 을 어 겼 습 니 다. 한 노드 로 모든 경 로 를 업데이트 합 니 다)
마이너스 변 의 그림 을 가지 고 계산 할 수 있다.
임의의 두 점 (i, j) 사이 에 매번 하나의 노드 를 사용 하여 모든 경 로 를 업데이트 합 니 다.동시에 우 리 는 임의의 두 점 사이 의 최 단 거 리 는 최대 n - 1 개의 결점 을 거 친 다 는 것 을 안다
이렇게 되면 특정 두 가지 점 에 가입 하 는 점 의 순 서 는 중요 하지 않다.
1. 더 이상 두 가 지 를 원 하지 않 는 길, 상관 없어
2. 두 점 과 직접적 으로 연결 되 어 간접 적 으로 연결 되 어 우리 의 사고 에 부합된다.
3. 가장 중요 하 다. 순서 가 없 으 면 중간 하나 부터 시작 하면 어 떡 하지?
중간 점 이 라면 그 와 연 결 된 점 간 의 가장 짧 은 경 로 를 업데이트 할 것 이다. 그러면 다음 중간 점 에 도움 이 되 고 '중간 길' 을 먼저 닦 은 셈 이다.
//d[i][j] i j
// path[i][j] i j j
//d[i][j] i j
void Floyd(int num,int **path,int**d,int **a)
{
int i,j,k;
for(i=0;id[i][k]+d[k][j])// i j
{
d[i][j]=d[i][k]+d[k][j];
path[i][j]=path[i][k];
}
}
Bellman-Ford
이전의 가장 짧 은 경 로 를 구 하 는 것 은 그림 에 마이너스 변 이 없 기 때문에 이 알고리즘 은 마이너스 변 이 있 는 그림 의 가장 짧 은 경 로 를 구 할 수 있다.
각 변 을 이완 시 키 고 매번 이완 시 키 면 적어도 하나의 도착 점 을 증가 시 킬 수 있 기 때문에 외부 순환 은 v - 1 회 까지 이다.
디 제 스 트 라 와 다른 점 은 디 제 스 트 라 는 매번 하나의 점 을 사용 하여 업 데 이 트 를 한 후에 사용 하지 않 고 베 르 만 의 모든 변 을 매번 사용 한 다 는 것 이다.
디 제 스 트 라 는 매번 찾 은 최 단 로 의 집합 에서 찾 지 못 한 집합 으로 연결 되 는 길 을 찾 아 내부 의 점 을 모 으 는 최 단 로 를 다시 계산 하지 않 는 다.
설명:
dijkstra , (dmin), (d[i]
:
- , , , 。 , , 。 , , ; - , |V | − 1 , |V | 。 , , 。 - 。
- O(|V|·|E|) ,|V| |E| )。
:
#include
using namespace std;
const int maxnum = 100;
const int maxint = 99999;
// ,
typedef struct Edge{
int u, v; // ,
int weight; //
}Edge;
Edge edge[maxnum]; //
int dist[maxnum]; //
int nodenum, edgenum, source; // , ,
//
void init()
{
// , ,
cin >> nodenum >> edgenum >> source;
for(int i=1; i<=nodenum; ++i)
dist[i] = maxint;
dist[source] = 0;
for(int i=1; i<=edgenum; ++i)
{
cin >> edge[i].u >> edge[i].v >> edge[i].weight;
if(edge[i].u == source) //
dist[edge[i].v] = edge[i].weight;
}
}
//
void relax(int u, int v, int weight)
{
if(dist[v] > dist[u] + weight)
dist[v] = dist[u] + weight;
}
bool Bellman_Ford()
{
for(int i=1; i<=nodenum-1; ++i)
for(int j=1; j<=edgenum; ++j)
relax(edge[j].u, edge[j].v, edge[j].weight);
bool flag = 1;
//
for(int i=1; i<=edgenum; ++i)
if(dist[edge[i].v] > dist[edge[i].u] + edge[i].weight)
{
flag = 0;
break;
}
return flag;
}
int main()
{
//freopen("input3.txt", "r", stdin);
init();
if(Bellman_Ford())
for(int i = 1 ;i <= nodenum; i++)
cout << dist[i] << endl;
return 0;
}
SPFA
초기 화 할 때 가장자리 만 추가 하고, 가장자리 에 추가 하지 않 으 면 버 티 지 않 습 니 다.
대기 열 을 사용 하여 Bellman - ford 알고리즘 을 최적화 하 는 원 리 는 다음 과 같다.
매번 모든 변 을 한 번 씩 이완 시 키 는 것 은 아니 며, 지난번 에 업 데 이 트 된 점 과 연 결 된 변 만 이 다음 이완 에 효과 가 있다.SPFA 는 이런 것들 을 기 록 했 습 니 다. 방금 업데이트 가 됐 습 니 다.
한 점 이 N 번 들 어가 면 이 그림 에 고리 가 있다 고 판단 하고 퇴장 합 니 다.팀 이 비 거나 탈퇴 합 니 다.
초기 화 할 때 시작 점 만 들 어 갑 니 다./*
( )
( , ) point
point , 1( v+1 ), point[1]=1,point[v+1]=E+1.
i, [point[i],point[i+1]-1]
point[i]=point[i+1], 。
*/
int SPFA(int source)
{
int i,j,flag,node;
int tag[nodenum]={0};
for(i=0;idist[u[i]]+w[i])
{
dist[v[i]]=dist[u[i]]+w[i],heap[tail++]=v[i];
tag[v[i]]++;
if(tag[v[i]]>=nodenum)
return 1;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
HDU 1874: 원활 한 공사 계속 [Dijkstra & SPFA & Floyd]모 성 은 여러 해 동안 의 원활 한 공사 계획 을 실행 한 후에 마침내 많은 길 을 건설 하 였 다.길 을 많이 건 너 지 않 아 도 좋 지 않다. 한 도시 에서 다른 도시 로 갈 때마다 여러 가지 도로 방안 을 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.