算法:
Floyed算法(O(n^3))
Dijkstra (适合稠密图)
SPFA:优点是可以处理负权值,但是不能处理负环,使用前最好先判断是否有负环(适合稀疏图)(还不熟)*
会用到的存图方法:
邻接矩阵
邻接表
前向星 (待学)
进度:
1.MPI Maelstrom POJ1502 (无向图)
题目在此
一开始看错了题意,以为需要对所有dis求和,实际上只需要取最大值
stoi不能用,可以用atoi(char*转化成int)
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
using namespace std;
const int MAX = 105;
const int inf = 0x3f3f3f;
int n,ans;
int dis[MAX];//表示从起点到i的最短距离
bool vis[MAX];
//vector<int> v[MAX];
int adj[MAX][MAX];
int x, mindis;
void init() {
ans = 0;
memset(vis, 0, sizeof(vis));
memset(dis, inf, sizeof(dis));
/*for (int i = 1; i < MAX; i++) {
v[i].clear();
}*/
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
adj[i][j] = inf;
}
}
dis[1] = 0;
}
int main() {
cin >> n;
init();
for (int i = 2; i <= n; i++) {
char ss[10];
int s;
for (int j = 1; j <= i - 1; j++) {
scanf("%s", ss);
if (strcmp(ss,"x")!=0) {
s = atoi(ss);
adj[i][j] = adj[j][i] = s;
}
}
}
for (int i = 1; i <= n; i++) {
x = -1;
mindis = inf;
for (int j = 1; j <= n; j++) {
if (!vis[j] && dis[j] < mindis) {
mindis = dis[j];
x = j;
}
}
vis[x] = 1;
for (int j = 1; j <= n; j++) {
if (!vis[j]) {
dis[j] = min(dis[j], dis[x] + adj[x][j]);
}
}
}
for (int i = 1; i <= n; i++) {
if (ans < dis[i])
ans = dis[i];
}
cout << ans << endl;
return 0;
}
2.Cow Contest POJ3660 (Floyed算法)
题目在此
看了一眼题解豁然开朗,用Floyed松弛
用memset只适合置0/-1/0x3f3f3f3f
代码:
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
const int MAX = 105;
const int INF = 0x3f3f3f;
int adj[MAX][MAX];
int main() {
for (int i = 1; i < MAX; i++) {
for (int j = 1; j < MAX; j++) {
adj[i][j] = INF;
}
}
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int a, b;
cin >> a >> b;
adj[a][b] = 1;//a比b强
adj[b][a] = -1;//b比a弱
}
for (int j = 1; j <= n; j++) {
for (int i = 1; i <= n;i++) {
for (int k = 1; k <= n; k++) {
if (adj[i][j] == adj[j][k] && (adj[i][j] == 1 || adj[i][j] == -1)) {//连赢或连输,可松弛
adj[i][k] = adj[i][j];
}
}
}
}
int ans = 0;
for (int i = 1; i <= n; i++) {
int sum = 0;
for (int j = 1; j <= n; j++) {
if (adj[i][j] != INF)
sum++;
}
if (sum == n - 1)//和其他所有牛都能比较,他就赢了
ans++;
}
cout << ans << endl;
return 0;
}
3.Tram POJ1847
只要能看出是最短路就比较简单,不搬开关权值是0,搬开关权值是1
题目在此
代码:
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int MAX = 105;
const int INF = 0x3f3f3f3f;
int adj[MAX][MAX],dis[MAX],ans,n;
bool vis[MAX];
int x, mindis,a,b;
struct node {
int v,w;
};
vector<node> mp[MAX];
void init() {
ans = 0;
for (int i = 0; i < MAX; i++) {
dis[i] = INF;
vis[i] = 0;
}
dis[a] = 0;
memset(adj, INF, sizeof(adj));
}
int main() {
int num;
cin >> n >> a >> b;
init();
for (int i = 1; i <= n; i++) {
cin >> num;
for (int j = 1; j <= num; j++) {
int x;
cin >> x;
if (j == 1)
adj[i][x] = 0;
else
adj[i][x] = 1;
}
}
for (int i = 1; i <= n; i++) {
x = -1;
mindis = INF;
for (int j = 1; j <= n; j++) {
if (!vis[j] && mindis > dis[j]) {
mindis = dis[j];
x = j;
}
}
vis[x] = 1;
for (int j = 1; j <= n; j++) {
if (!vis[j]) {
dis[j] = min(dis[j], dis[x] + adj[x][j]);
}
}
}
if (dis[b] == INF)
puts("-1");
else
cout << dis[b] << endl;
return 0;
}
4.Silver Cow Party POJ3268
网址在此
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAX 1005
const int inf = 0x3f3f3f;
using namespace std;
int adj[MAX][MAX], dis[MAX], ret[MAX];
int a[MAX], b[MAX];
bool vis[MAX];
void init(int n,int x) {
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) {
dis[i] = inf;
ret[i] = inf;
}
dis[x] = 0;
ret[x] = 0;
}
int main() {
int n, m, x;
cin >> n >> m >> x;
init(n, x);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
adj[i][j] = inf;
}
}
//城镇数,路数,party城
for (int i = 1; i <= m; i++) {
int a, b, s;
cin >> a >> b >> s;
if (s < adj[a][b])
adj[a][b] = s;
}
/*for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << adj[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;*/
for (int i = 1; i <= n; i++) {
int mindis = inf;
int t = -1;
for (int j = 1; j <= n; j++) {
if (!vis[j] && dis[j] < mindis) {
mindis = dis[j];
t = j;
}
}
vis[t] = 1;
for(int j=1;j<=n;j++){//松弛
if (!vis[j])
dis[j] = min(dis[j],
dis[t] + adj[t][j]);
}
}
for (int i = 1; i <= n; i++) {
a[i] = dis[i];
}
a[x] = 0;//a表示从x回来的距离
//到此为止正过程结束
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
swap(adj[i][j], adj[j][i]);
}
}
init(n, x);
/*for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << adj[i][j] << " ";
}
cout << endl;
}*/
for (int i = 1; i <= n; i++) {
int mindis = inf;
int t = -1;
for (int j = 1; j <= n; j++) {
if (!vis[j] && dis[j] < mindis) {
mindis = dis[j];
t = j;
}
}
vis[t] = 1;
for (int j = 1; j <= n; j++) {//松弛
if (!vis[j])
dis[j] = min(dis[j],
dis[t] + adj[t][j]);
}
}
for (int i = 1; i <= n; i++) {
b[i] = dis[i];
}
b[x] = 0;
int ans = 0;
for (int i = 1; i <= n; i++) {
ans = max(ans, a[i] + b[i]);
}
cout << ans << endl;
return 0;
}