Heavy Transportation POJ - 1797
题意:
有n个城市,m条道路,在每条道路上有一个承载量,现在要求从1到n城市最大承载量,而一条路径的最大承载量是其中每条路的承载量的最小值。而最大承载量就是从城市1到城市n每条通路上的最小承载量的最大值
思路:
这道题目要求的是从1到N各个路径最小值的最大值,即d[y]=max(d[y],min(d[x],m[x][y]))。
/*
* Dijkstra 邻接矩阵
*/
#include
#include
#include
#include
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef long long LL;
const LL maxn = 1010;
const int inf = 1<<30;
int N, M, W[maxn][maxn];
int d[maxn]; //到达i点的最大最小值
bool used[maxn];
int dijkstra(){
ms(used, 0);
for(int i = 1; i <= N; i++)
d[i] = W[1][i]; //初始化d
used[1] = true;
while(true){
int u = 0, curMax = 0;
for(int i = 1; i <= N; i++)
if(!used[i] && d[i]>curMax)
curMax = d[i], u = i;
if(u == 0) break;
used[u] = true;
for(int v = 1; v <= N; v++)
if(!used[v])
d[v] = max(min(curMax, W[u][v]), d[v]);
}
return d[N];
}
int main()
{
int T, u, v, w;
cin >> T;
for(int t = 1; t <= T; t++){
ms(W, 0);
cin >> N >> M;
for(int i = 1; i <= M; i++){
cin >> u >> v >> w;
W[u][v] = W[v][u] = w;
}
cout << "Scenario #"<< t <<":" <<endl;
cout << dijkstra() << endl << endl;
}
return 0;
}
/*
* Dijkstra 链式前向星
*/
#include
#include
#include
#include
using namespace std;
const int maxn = 1e5 + 10;
const int inf = 1e9 + 7;
int head[maxn], d[maxn];
bool vis[maxn];
int n, m, cnt;
struct node{
int v, nex, len;
}edge[maxn];
void addedge(int u, int v, int len)
{
edge[cnt].v = v;
edge[cnt].nex = head[u];
edge[cnt].len = len;
head[u] = cnt++;
}
void dijkstra(int s)
{
fill(d, d + maxn, inf);
d[s] = 0;
for(int i = 1; i <= n; i++) {
int u = -1, MIN = inf;
for(int j = 1; j <= n; j++) {
if(vis[j] == false && d[j] < MIN) {
u = j;
MIN = d[j];
}
}
vis[u] = true;
for(int j = head[u]; j != -1; j = edge[j].nex) {
int v = edge[j].v;
if(vis[v] == false && d[u] + edge[j].len < d[v]) {
d[v] = d[u] + edge[j].len;
}
}
}
}
void init()
{
memset(head, -1, sizeof(head));
}
int main()
{
ios::sync_with_stdio(false);
init();
int s, t;
cin >> n >> m >> s >> t;
int x, y, z;
for(int i = 1; i <= m; i++) {
cin >> x >> y >> z;
addedge(x, y, z);
addedge(y, x, z);
}
dijkstra(s);
cout << d[t] << endl;
return 0;
}
/*
spfa邻接矩阵
4156K 469MS
*/
#include
#include
using namespace std;
#define MAXV 1010
#define min(a,b) (a
int map[MAXV][MAXV],n,m;
int spfa(){
queue <int>q;
int i,j,v;
int vis[MAXV],d[MAXV];
for(i=1;i<=n;i++){
vis[i]=0;
d[i]=0;
}
q.push(1);
vis[1]=1;
while(!q.empty()){
v=q.front();q.pop();
vis[v]=0;
for(i=1;i<=n;i++){
if(v==1 && map[v][i]){
d[i]=map[v][i];
q.push(i);
vis[i]=1;
continue;
}
if(d[i]<min(d[v],map[v][i])){
d[i]=min(d[v],map[v][i]);
if(!vis[i]){
vis[i]=1;
q.push(i);
}
}
}
}
return d[n];
}
int main(){
int t,i,j,sum,a,b,c;
scanf("%d",&sum);
for(t=1;t<=sum;t++){
scanf("%d%d",&n,&m);
for(i=0;i<=n;i++)
for(j=0;j<=n;j++)
map[i][j]=0;
for(i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
map[a][b]=map[b][a]=c;
}
printf("Scenario #%d:\n",t);
printf("%d\n\n",spfa());
}
return 0;
}
/*
spfa链式前向星
4156K 469MS
*/
#include
#include
#include
#include
#include
using namespace std;
const int manx=1e6+5;
const int mamx=1e6+5;
int head[manx],d[manx];
bool vis[manx];
struct node{
int v,w,next;
}a[mamx];
int n,m,s,e,k=0;
void add(int u,int v,int w)
{
a[++k].next=head[u];
a[k].w=w;
a[k].v=v;
head[u]=k;
}
void spfa()
{
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
d[s]=1e9;
queue<int>q;
q.push(s);
while(q.size())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i;i=a[i].next)
{
int v=a[i].v,w=a[i].w;
if(d[v]<min(d[u],w)) {
d[v]=min(d[u],w);
if(!vis[v])
q.push(v),vis[v]=1;
}
}
}
}
int main()
{
int t;
cin>>t;
for(int o=1;o<=t;o++)
{
scanf("%d%d",&n,&m);
s=1,e=n,k=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
spfa();
printf("Scenario #%d:\n",o);
printf("%d\n",d[e]);
printf("\n");
}
return 0;
}
/*
* dijkstra 优先队列 链式前向星优化
*/
#include
#include
#include
#include
#include
using namespace std;
const int N = 1005, M = 200005, INF = 0x3f3f3f3f;
int t, n, m, u, v, w, len, h[N], d[N];//d[i]代表1到i的路径中的最小值中的最大一个
bool vis[N];
struct E {
int v, w, next;
} e[M];
struct Node {
int v, d;
Node(int d, int v): d(d), v(v){}
bool operator < (const Node&w) const {
return d < w.d;//d大的应该先出来
}
};
void add(int u, int v, int w) {
e[len].v = v;
e[len].next = h[u];
e[len].w = w;
h[u] = len++;
}
void djkstra() {
memset(vis, false, sizeof(vis));
memset(d, 0, sizeof(d));
d[1] = INF; //第一个点应该是无穷大
priority_queue<Node> q;
q.push(Node(0, 1));
while (!q.empty()) {
int u = q.top().v;
q.pop();
if (vis[u]) continue;
vis[u] = true;
for (int j = h[u]; j; j = e[j].next) {
int v = e[j].v;
int w = min(d[u], e[j].w); //看这条边 和之前的最小值谁小
if (d[v] < w) {
d[v] = w;
q.push(Node(d[v], v));
}
}
}
}
int main() {
scanf("%d", &t);
for (int cas = 1; cas <= t; cas++) {
memset(h, 0, sizeof(h)), len = 1;
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &u, &v, &w);
add(u, v, w); add(v, u, w);
}
djkstra();
printf("Scenario #%d:\n%d\n\n", cas, d[n]);
}
return 0;
}