写之前先给这个专题做个总结
知识点:单源最短路,全源最短路,求最短路中的最长边,bellman ford算法求有负权的最短路,bellman or SPFA判断环,反向建图,差分约束,层次图建立层点(连通点)。

应该是覆盖最短路所有内容了

1.POJ 2387 Til the Cows Come Home

模板题

2.POJ 2253 Frogger

Floyd模板题,只要看到这个数据范围冲就完事了(n<=800)

3.POJ 1797 Heavy Transportation

题意:求能到达终点的最大边权最小
看题意很明显这个题可以用二分答案做,然而我一直莫名其妙的wa?用最大生成树的最小边也wa,然后换了变形dij才过…
dij的堆要写成大根堆,因为要优先选择边权大,不然会wa

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
#define maxn 200010
#define maxm 200010
using namespace std;
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
struct edge{int v,w;
}e[maxm];
int cnt,n,m,s,vis[maxn],dis[maxn];
vector<edge>p[100005];
struct node{int w,now;bool operator <(const node&x)const{return w<x.w;}
};
priority_queue<node>q;
inline void dij(int s){memset(dis,0,sizeof(dis));memset(vis,0,sizeof(vis));dis[s]=0x3f3f3f3f;q.push((node){0,s});while(!q.empty()){node x=q.top();q.pop();int u=x.now;if(vis[u])continue;vis[u]=1;for(int i=0;i<p[u].size();i++){int v=p[u][i].v;if(dis[v]<min(dis[u],p[u][i].w)){dis[v]=min(dis[u],p[u][i].w);q.push((node){dis[v],v});}}}
}
signed main(){int tt,qq=0;cin>>tt;while(tt--){qq++;n=read(),m=read();memset(p,0,sizeof(p));for(int i=1,x,y,z;i<=m;i++){x=read(),y=read(),z=read();p[x].push_back((edge){y,z});p[y].push_back((edge){x,z});}dij(1);printf("Scenario #%d:\n",qq);printf("%d\n\n",dis[n]);}return 0;
}

4.POJ 3268 Silver Cow Party

题意:求所有牛来回party最短路的最大值
见到这种来回的,一般都是直接建反图就完事了

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
#define maxn 200010
#define maxm 200010
const int inf=0x3f3f3f3f;
using namespace std;
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
struct edge{int v,w;
}e[maxm];
int cnt,n,m,mm,s,vis[maxn],dis[maxn],dis1[maxn],vis1[maxn];
vector<edge>p[100005],p1[100005];
struct node{int w,now;bool operator <(const node&x)const{return w>x.w;}
};
inline void dij(int s){priority_queue<node>q;for(int i=1;i<=n;i++){dis[i]=inf;}memset(vis,0,sizeof(vis));dis[s]=0;q.push((node){0,s});while(!q.empty()){node x=q.top();q.pop();int u=x.now;if(vis[u])continue;vis[u]=1;for(int i=0;i<p[u].size();i++){int v=p[u][i].v;if(dis[v]>dis[u]+p[u][i].w){dis[v]=dis[u]+p[u][i].w;q.push((node){dis[v],v});}}}
}
inline void dij1(int s){priority_queue<node>q;for(int i=1;i<=n;i++){dis1[i]=inf;}memset(vis1,0,sizeof(vis1));dis1[s]=0;q.push((node){0,s});while(!q.empty()){node x=q.top();q.pop();int u=x.now;if(vis1[u])continue;vis1[u]=1;for(int i=0;i<p1[u].size();i++){int v=p1[u][i].v;if(dis1[v]>dis1[u]+p1[u][i].w){dis1[v]=dis1[u]+p1[u][i].w;q.push((node){dis1[v],v});}}}
}
signed main(){n=read(),m=read(),s=read();mm=0;for(int i=1,x,y,z;i<=m;i++){x=read(),y=read(),z=read();p[x].push_back((edge){y,z});p1[y].push_back((edge){x,z});}for(int i=1;i<=n;i++){if(i==s)continue;dij(i);dij1(i);mm=max(mm,dis[s]+dis1[s]);//  cout<<i<<" "<<dis[s]<<" "<<dis1[s]<<endl;}cout<<mm;return 0;
}

5.POJ 1860 Currency Exchange

读题难度>解题难度
判环模板题

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
#define maxn 200010
#define maxm 200010
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,cnt,ans,c=1;
double r1,r2,c1,c2;
int k;
double money;
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
struct edge{int u,v;double r,c;
};
vector<edge>e;
double d[1005];
bool bellman(){memset(d,0,sizeof(d));d[k]=money;for(int i=1;i<n;i++){int ok=0;for(int j=0;j<e.size();j++){if((d[e[j].u]-e[j].c)*e[j].r>d[e[j].v]){d[e[j].v]=(d[e[j].u]-e[j].c)*e[j].r;ok=1;}}if(!ok)break;}for(int i=0;i<e.size();i++){if((d[e[i].u]-e[i].c)*e[i].r>d[e[i].v]){return true;}}return false;
}
signed main(){cin>>n>>m>>k>>money;for(int i=1;i<=m;i++){int x,y;cin>>x>>y>>r1>>c1>>r2>>c2;e.push_back((edge){x,y,r1,c1});e.push_back((edge){y,x,r2,c2});}if(bellman())cout<<"YES"<<endl;else cout<<"NO"<<endl;return 0;
}

6.POJ 3259 Wormholes

判环,比上一题还简单,故略

7.POJ 1502 MPI Maelstrom

读入难度>>解题难度
读x的时候一定要注意这个坑…用string的话会出问题
读入完直接跑Floyd就没了

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
#define maxn 200010
#define maxm 200010
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,w,cnt,ans,c=1;
int dis[105][105];
int main(){cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i==j)dis[i][j]=0;else dis[i][j]=inf;}}for(int i=2;i<=n;i++){for(int j=1;j<=i-1;j++){char x[50];scanf("%s",x);if(x[0]=='x'){continue;}else{int k=atoi(x);dis[i][j]=k;dis[j][i]=k;}}}for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);}}}int mm=0;for(int i=2;i<=n;i++){if(dis[1][i]!=inf){mm=max(mm,dis[1][i]);}}cout<<mm<<endl;return 0;
}

8.POJ 3660 Cow Contest

给出一些列大小关系,问有多少头牛的排名可以确定
思路其实很简单,以大小关系建立单向边,跑一遍Floyd,求出来dis[i][j]的值不为inf就cnt[i] ,cnt[j]都+1,统计完之后如果值为n-1就代表跟所有其他的牛都有确定大小关系,即为答案

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,t,ans,mxn;
int dis[505][505],vis[505][505],cnt[505];
int main(){cin>>n>>m;memset(dis,inf,sizeof(dis));for(int i=1;i<=m;i++){int x,y;cin>>x>>y;dis[x][y]=1;}for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);}}}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i==j)continue;if(dis[i][j]!=inf)cnt[j]++,cnt[i]++;}}for(int i=1;i<=n;i++){if(cnt[i]==n-1)ans++;}cout<<ans;return 0;
}

9.POJ 2240 Arbitrage

套利,判环,这题之前在洛谷上面做过,用map乱搞,跑Floyd判断是否有dis最终大于1,有就是有环,然而交vj直接给我TLE,换成bellman 判环 TLE,(poj懂的都懂好吧)没有氧气优化又没有C++11真的吐了,傻逼测评姬

最终 SPFA判环可过

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
int n,f;
double dis[50][50];
string a;
map<string,int>m;
double s;
string x,y;
struct edge{int v;double w;
};
vector<edge>e[5005];
double d[1005];
int cnt[10050];
int vis[10050];
bool spfa(){int ct=0;memset(cnt,0,sizeof(cnt));queue<int>q;for(int i=1;i<=n;i++){d[i]=1;vis[i]=1,q.push(i);}while(!q.empty()){int u=q.front();q.pop();vis[u]=0;for(int i=0;i<e[u].size();i++){int v=e[u][i].v;double w=d[u]*e[u][i].w;if(d[v]<w){d[v]=w;cnt[v]=cnt[u]+1;if(ct>4*n)return true;if(cnt[v]>=n)return true;if(vis[v]==0)q.push(v),vis[v]=1;}}}return false;
}
int main(){while(1){int t;f++;cin>>t;if(t==0)break;m.clear();memset(e,0,sizeof(e));for(int i=1;i<=t;i++){cin>>a;m[a]=i;}cin>>n;for(int i=1;i<=n;i++){double z;cin>>x>>z>>y;e[m[x]].push_back((edge){m[y],z});}if(spfa())printf("Case %d: Yes\n",f);else printf("Case %d: No\n",f);}return 0;
}

10.POJ 1511 Invitation Cards

UVA721
在vj上面一直wa,为了验证我的程序是对的,特意注册账号去UVA交了原题,AC了,poj爬
思路:建反图
(本代码在vj上过不了)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
#define maxn 1000010
#define maxm 1000010
const int inf=0x3f3f3f3f;
using namespace std;
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
struct edge{int v,w;
}e[maxm];
int cnt,n,m,mm,s,vis[maxn],dis[maxn],dis1[maxn],vis1[maxn];
vector<edge>p[1000005],p1[1000005];
struct node{int w,now;bool operator <(const node&x)const{return w>x.w;}
};
inline void dij(int s){priority_queue<node>q;for(int i=1;i<=n;i++){dis[i]=inf;}memset(vis,0,sizeof(vis));dis[s]=0;q.push((node){0,s});while(!q.empty()){node x=q.top();q.pop();int u=x.now;if(vis[u])continue;vis[u]=1;for(int i=0;i<p[u].size();i++){int v=p[u][i].v;if(dis[v]>dis[u]+p[u][i].w){dis[v]=dis[u]+p[u][i].w;q.push((node){dis[v],v});}}}
}
inline void dij1(int s){priority_queue<node>q;for(int i=1;i<=n;i++){dis1[i]=inf;}memset(vis1,0,sizeof(vis1));dis1[s]=0;q.push((node){0,s});while(!q.empty()){node x=q.top();q.pop();int u=x.now;if(vis1[u])continue;vis1[u]=1;for(int i=0;i<p1[u].size();i++){int v=p1[u][i].v;if(dis1[v]>dis1[u]+p1[u][i].w){dis1[v]=dis1[u]+p1[u][i].w;q.push((node){dis1[v],v});}}}
}
signed main(){int tt;cin>>tt;while(tt--){n=read(),m=read();mm=0;memset(p,0,sizeof(p));memset(p1,0,sizeof(p1));for(int i=1,x,y,z;i<=m;i++){x=read(),y=read(),z=read();p[x].push_back((edge){y,z});p1[y].push_back((edge){x,z});}dij(1);dij1(1);for(int i=2;i<=n;i++){mm+=dis[i]+dis1[i];}cout<<mm<<endl;}return 0;
}

11.POJ 3159 Candies

差分约束,太水了,甚至不能算模板,直接用dij建单边就过了
模板在后面

12.POJ 2502 Subway

此题难点在于建图,建图难度>>解题难度
对每个相间车站建直线距离边,再对所有点建欧几里得距离边,最后跑一遍dij

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
#define maxn 200010
#define maxm 200010
#define inf 0x3f3f3f3f
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
struct edge{int v;double w;
}e[maxm];
int num;
int cnt,n,m,s,vis[maxn];
double dis[maxn];
vector<edge>p[100005];
struct node{double w;int now;bool operator <(const node&x)const{return w>x.w;}
};
priority_queue<node>q;
inline void dij(int s){for(int i=1;i<=num;i++){dis[i]=inf;}memset(vis,0,sizeof(vis));dis[s]=0;q.push((node){0,s});while(!q.empty()){node x=q.top();q.pop();int u=x.now;if(vis[u])continue;vis[u]=1;for(int i=0;i<p[u].size();i++){int v=p[u][i].v;if(dis[v]>dis[u]+p[u][i].w){dis[v]=dis[u]+p[u][i].w;q.push((node){dis[v],v});}}}
}
double juli(double x1,double y1,double x2,double y2,double tt){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))/tt/1000*60;
}
struct ta{double x,y;
}stop[505];
int sx,sy,dx,dy;
int main(){sx=read(),sy=read(),dx=read(),dy=read();stop[1].x=sx;stop[1].y=sy;memset(dis,0x3f3f3f3f,sizeof(dis));int x,y;num=2;while(~scanf("%d%d",&x,&y)){stop[num].x=x,stop[num].y=y;int xx,yy;while(~scanf("%d%d",&xx,&yy)){if(xx==-1&&yy==-1)break;stop[num+1].x=xx;stop[num+1].y=yy;double d=juli(x,y,xx,yy,40);p[num].push_back((edge){num+1,d});p[num+1].push_back((edge){num,d});x=xx;y=yy;num++;}num++;}stop[num].x=dx;stop[num].y=dy;for(int i=0;i<=num;i++){for(int j=0;j<=num;j++){if(i==j)continue;double d=juli(stop[i].x,stop[i].y,stop[j].x,stop[j].y,10);p[i].push_back((edge){j,d});}}dij(1);printf("%.f",dis[num]);return 0;
}

13.POJ 1062 昂贵的聘礼

此题的题意真的是坑的让人吐血…最开始理解成探险家最开始等级无限,接触一个人之后就降等,降等之后不能跟高级商家交易,结果真正的题意是:探险家接触过的所有人的等级差距都不能超过m
比如酋长的等级是5,m是2,你最开始跟等级7的人交易过,你就不能再跟<5的人交易了,所有其实是询问长度为m的一个区间(并且酋长的等级一定要包含在区间内),一共跑m+1次dij,建图很简单,每个物品从0向它建一条原价边,再从它的前置物建优惠边即可

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
#define maxn 200010
#define maxm 200010
#define inf 0x3f3f3f3f
#define int long long
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
struct edge{int v,w,dengji;
}e[maxm];
int cnt,n,m,s,vis[maxn],dis[maxn];
vector<edge>p[100005];
struct node{int w,now;bool operator <(const node&x)const{return w>x.w;}
};
priority_queue<node>q;
inline void dij(int s,int dj1,int dj2){for(int i=1;i<=n;i++){dis[i]=inf;}memset(vis,0,sizeof(vis));dis[0]=0;q.push((node){0,s});while(!q.empty()){node x=q.top();q.pop();int u=x.now;if(vis[u])continue;vis[u]=1;for(int i=0;i<p[u].size();i++){int v=p[u][i].v;if(dis[v]>dis[u]+p[u][i].w&&p[u][i].dengji>=dj1&&p[u][i].dengji<=dj2){dis[v]=dis[u]+p[u][i].w;q.push((node){dis[v],v});}}}
}
signed main(){m=read(),n=read();int zui;for(int i=1;i<=n;i++){int money,dj,q;money=read(),dj=read(),q=read();if(i==1)zui=dj;p[0].push_back((edge){i,money,dj});for(int j=1;j<=q;j++){int x,y;x=read(),y=read();p[x].push_back((edge){i,y,dj});}}int qq=m;int mm=0x3f3f3f3f;for(int i=1;i<=m+1;i++){dij(0,zui-qq,zui-qq+m);
//      cout<<zui-qq<<" "<<zui-qq+m<<endl;;qq--;mm=min(dis[1],mm);}cout<<mm;return 0;
}

14.POJ 1847 Tram

每个车站第一条边权为0,其他为1,然后就是Floyd傻逼题了

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
#define maxn 200010
#define maxm 200010
#define inf 0x3f3f3f3f
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
int dis[105][105];
int a,b,n;
int m;
signed main(){cin>>n>>a>>b;memset(dis,inf,sizeof(dis));for(int i=1;i<=n;i++){int t;cin>>t;for(int j=1;j<=t;j++){int x;x=read();if(j==1)dis[i][x]=0;else dis[i][x]=1;}}
//  for(int i=1;i<=n;i++){//      for(int j=1;j<=n;j++){///         cout<<dis[i][j]<<" ";
//      }
//      cout<<endl;
//  }for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);}}}if(dis[a][b]!=inf)cout<<dis[a][b];else cout<<"-1";return 0;
}

15.LightOJ 1074 Extended Traffic

三次方会出负数…spfa判环
询问的点不在环上且可到达输出距离,否则直接疑惑

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
#define maxn 200010
#define maxm 200010
#define inf 0x3f3f3f3f
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
int d[5005];
int n,a[5005],q[5005];
int m,vis[5005],cs[5005];
struct edge{int v,w;
};
vector<edge>e[5005];
void spfa(){memset(d,inf,sizeof(d));memset(vis,0,sizeof(vis));memset(cs,0,sizeof(cs));queue<int>q;d[1]=0;cs[1]=1;q.push(1);while(!q.empty()){int u=q.front();q.pop();vis[u]=0;for(int i=0;i<e[u].size();i++){int v=e[u][i].v;int w=e[u][i].w;if(d[v]>d[u]+w){d[v]=d[u]+w;if(vis[v]==0&&cs[v]<=n){cs[v]++;q.push(v);vis[v]=1;}}}}
}
signed main(){int tt,qq=0,p;cin>>tt;while(tt--){cin>>n;qq++;for(int i=1;i<=n;i++){a[i]=read();}cin>>m;for(int i=1;i<=m;i++){int u,v;u=read(),v=read();int dis=(a[v]-a[u])*(a[v]-a[u])*(a[v]-a[u]);e[u].push_back((edge){v,dis});}cin>>p;for(int i=1;i<=p;i++){q[i]=read();}spfa();printf("Case %d:\n",qq);for(int i=1;i<=p;i++){if(d[q[i]]<3||d[q[i]]>=inf||cs[q[i]]>n){printf("?\n");}else{printf("%d\n",d[q[i]]);}}memset(e,0,sizeof(e));}return 0;
}

16.HDU 4725 The Shortest Path in Nya Graph

建图题
每个点有它所属的层,层之间有通道,对层之间所有点全部建边肯定会炸,所以建立每一层的层点,即专门用来连接属于这一层其他点的点

#include<bits/stdc++.h>
using namespace std;
#define maxn 200010
#define maxm 200010
#define inf 0x3f3f3f3f
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
struct edge{int v,w;
}e[maxm];
int cnt,n,m,c,vis[maxn],dis[maxn];
vector<edge>p[200005];
int cs[200005],layer[200005];
struct node{int w,now;bool operator <(const node&x)const{return w>x.w;}
};
priority_queue<node>q;
inline void dij(int s){memset(dis,inf,sizeof(dis));memset(vis,0,sizeof(vis));dis[s]=0;q.push((node){0,s});while(!q.empty()){node x=q.top();q.pop();int u=x.now;if(vis[u])continue;vis[u]=1;for(int i=0;i<p[u].size();i++){int v=p[u][i].v;if(dis[v]>dis[u]+p[u][i].w){dis[v]=dis[u]+p[u][i].w;q.push((node){dis[v],v});}}}
}
signed main(){int tt;cin>>tt;for(int rr=1;rr<=tt;rr++){n=read(),m=read(),c=read();for(int i=1;i<=n;i++){layer[i]=read();cs[layer[i]]=1;}for(int i=1;i<=n;i++){p[layer[i]+n].push_back((edge){i,0});if(layer[i]-1>=1&&cs[layer[i]-1]==1){p[i].push_back((edge){layer[i]-1+n,c});}if(layer[i]+1<=n&&cs[layer[i]+1]==1){p[i].push_back((edge){layer[i]+1+n,c});}}for(int i=1,x,y,z;i<=m;i++){x=read(),y=read(),z=read();p[x].push_back((edge){y,z});p[y].push_back((edge){x,z});}//    cout<<endl<<endl;// for(int i=1;i<=n;i++){//     for(int j=0;j<p[i].size();j++){//         printf("%d %d %d\n",i,p[i][j].v,p[i][j].w);//     }// }dij(1);if(dis[n]==inf)printf("Case #%d: -1\n",rr);else printf("Case #%d: %d\n",rr,dis[n]);memset(layer,0,sizeof(layer));memset(cs,0,sizeof(cs));memset(p,0,sizeof(p));}return 0;
}

17.HDU 3416 Marriage Match IV

网络流,待补

18.HDU 4370 0 or 1


这题必须配放个图
此题是我有史以来读过题意最抽象的题目,没有之一,读了两个小时没读懂
题目给了一些条件和一个矩阵,要你求一个矩阵使两个矩阵对应点乘积和最小
思维转化,给出的条件代表点1的出度为1,点n的入度为1,其他的所有点出入度相等,路径长度非负,还有两种特殊情况,图中有从1 or n出发的环,这样的情况下其他的点入度出度全为0,也符合题目的条件
拿dij跑最短路,并判断特殊情况

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,a[305][305],d[305];
const int inf=0x3f3f3f3f;
int ans,h;
int vis[350];
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
void dij(int s){memset(d,inf,sizeof(d));memset(vis,false,sizeof(vis));d[s]=0;for(int i=1;i<=n;i++){int t=-1;for(int j=1;j<=n;j++){if(vis[j]==false&&(t==-1||d[t]>d[j])){t=j;}}vis[t]=true;for(int j=1;j<=n;j++){d[j]=min(d[j],d[t]+a[t][j]);if(j==s&&t!=s)h=min(h,d[t]+a[t][j]);}}
}
int main(){while(cin>>n){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){a[i][j]=read();}}h=inf;dij(1);ans=d[n];int t=h;h=inf;dij(n);t+=h;cout<<min(ans,t)<<endl;}
}

19.POJ 3169 Layout

差分约束模板来了
白书上经典例题
重点在于符号的判断>=和<=是两个方向,并且建立超级源点
建图完跑bellman即可

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
#define maxn 200010
#define maxm 200010
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,w,cnt,ans;
inline int read()
{int x=0,k=1; char c=getchar();while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();return x*k;
}
struct edge{int u,v,w;
};
vector<edge>e;
int d[1005];
bool bellman(){memset(d,inf,sizeof(d));d[1]=0;for(int i=1;i<n;i++){int ok=0;for(int j=0;j<e.size();j++){edge ee=e[j];if(d[ee.v]>d[ee.u]+ee.w){d[ee.v]=d[ee.u]+ee.w;ok=1;}}if(!ok)break;}for(int i=0;i<e.size();i++){edge ee=e[i];if(d[ee.v]>d[ee.u]+ee.w){return true;}}return false;
}
signed main(){int ml,md;n=read(),ml=read(),md=read();for(int i=1;i<=ml;i++){int u,v,w;u=read(),v=read(),w=read();e.push_back((edge){u,v,w});}for(int i=1;i<=md;i++){int u,v,w;u=read(),v=read(),w=read();e.push_back((edge){v,u,-w});}for(int i=1;i<=n-1;i++){e.push_back((edge){i+1,i,0});}if(bellman())cout<<"-1";else{if(d[n]>inf/2){cout<<"-2";}else {cout<<d[n];}}return 0;
}

由于前天晚上和昨天身体超级难受就慢了一点点…而且最后几个题把我拦住了…所以就花了三天

感觉写一下题解还是挺有用的,真正的理解是能解释给别人听让别人理解(费曼学习法),而且回顾整个专题也可以做一些反思,思考题与题之间的关联和区别,温故知新。

继续保持学习状态,冲!!!

要开始学高数和电路分析了(

刷题记录 kuangbin带你飞专题四:最短路练习相关推荐

  1. [kuangbin带你飞]专题四 最短路练习 B( POJ 2253) Frogger(spfa)

    B - Frogger(spfa) 题目链接:https://vjudge.net/contest/66569#problem/B 题目: Freddy Frog is sitting on a st ...

  2. [kuangbin带你飞]专题四 最短路练习 R

    http://acm.hdu.edu.cn/showproblem.php?pid=4370 HDU 4370 0 or 1(最短路) 这是整套里面我觉得最有意思的一道最短路,也确实让我觉得我与真正a ...

  3. [kuangbin带你飞]专题四 做题顺序与题解 【最短路练习】

    随便说点: 博主正在刷kuangbin专题的题目,初学者,没接触过什么算法,刷题的初衷是备战蓝桥杯,后来发现了算法资料大多是针对acm的,挑选kuangbin专题入门也是如此,毕竟这样分类看起来能达到 ...

  4. kuangbin带你飞专题合集

    题目列表 [kuangbin带你飞]专题一 简单搜索 [kuangbin带你飞]专题二 搜索进阶 [kuangbin带你飞]专题三 Dancing Links [kuangbin带你飞]专题四 最短路 ...

  5. “kuangbin带你飞”专题计划——专题十四:数论基础

    写在前面 1.目前还没啥写的.开始时间:2021-05-13(其实博客上看得到该博客创建时间的) 2.上一个专题刷的是网络流(博客总结),属于第一次接触.本来想的是一周特别高效,然后一周略划水,结果是 ...

  6. (2021-07-14~)“kuangbin带你飞”专题计划——专题十三:基础计算几何

    目录 前言 参考博客 自己总结的东西: 难度判断? 题目 1.[TOYS POJ - 2318 ](解决) 2.[Toy Storage POJ - 2398 ](解决) 3.[Segments PO ...

  7. $2019$ 暑期刷题记录 $2$(基本算法专题)

    $ 2019 $ 暑期刷题记录 $ 2 $ (基本算法专题) $ by~~wch $ $ BZOJ~1958~Strange~Towers~of~Hanoi $ (动态规划,递推) 题目大意: 求有 ...

  8. kuangbin带你飞 专题1-23 题单

    kuangbin大神,对于打过ACM比赛的ACMer,无人不知无人不晓. 在此,附上vjudge平台上一位大神整理的[kuangbin带你飞]专题目录链接. [kuangbin带你飞专题目录1-23] ...

  9. [kuangbin带你飞]专题十二 基础DP1 题解+总结

    kuangbin带你飞:点击进入新世界 总结: 简单dp,最近在做,持续更新. 文章目录 总结: 1.Max Sum Plus Plus 2.Ignatius and the Princess IV ...

  10. [kuangbin带你飞]专题五 并查集 题解+总结

    kuangbin带你飞:点击进入新世界 总结: 本人算是初学者中的初学者,欢迎交流~ 并查集的接触过的不多,大概只有普通并查集,带权并查集,种族并查集,传说中的可持续化并查集只是听说过还没有接触,不过 ...

最新文章

  1. Windows Server 2016 DNS Policy Geo-Location 1
  2. 2021春季学期-创新设计与实践-Lesson3
  3. linux服务器调用端口超时,Linux服务器可以ping,但是telnet端口超时,网站wget超时,访问超时的解决办法...
  4. linux 配置文件解析,任何可以在Linux上轻松解析配置文件的工具?
  5. MySQL where后面的行子查询使用
  6. awk文本工具按列计算和
  7. java 接口防刷_java轻量级接口限流/防刷插件
  8. sql数字转换为字符_Python|图片转换为字符画^_^
  9. JavaScript 变量及数据类型
  10. nodejs 异常的处理
  11. Returned object not currently part of this pool
  12. 记忆拼图·心灵风暴·黑洞生死书
  13. html播放mp4不显示画面,浏览器播放mp4格式视频时只有声音看不到画面的原因及解决方法(精)...
  14. Py之lime:lime库的简介、安装、使用方法之详细攻略
  15. 《可复制的领导力》脑图
  16. 搭建配置私服-nexus ,Maven中的使用——3
  17. #大话设计模式之适配器模式#
  18. iOS- 延迟1秒执行一个函数
  19. SaaS是什么?企业采购SaaS有什么好处?
  20. MAPI错误0x80040107

热门文章

  1. linux代码折叠,VIM 代码折叠 :set foldmethod=marker
  2. oracle in table类型,Oracle Built-in Data Types(Oracle内置数据类型)
  3. oracle数据库如何写翻页_在oracle数据库中的分页SQL语句怎么写?
  4. java nio 下载网页_JavaNIO 下载网络文件保存本地报java.nio.file.AccessDeniedException:无权限操作...
  5. Oracle asm aix盘,AIX添加ASM的裸盘,存储底层硬盘迁移
  6. 4g网络切换软件_游戏掉线坑队友?OPPO Reno网络切换超快,上分吃鸡更稳
  7. Swift 5 从Model, Struct或Class转Dictionary
  8. 容器技术Docker K8s 4 容器编排技术基础-Kubernetes
  9. 阿里云云计算 40 CDN的概念
  10. LeetCode--Reverse Integer(整数反转)Python