Dijkstra:
题目链接:POJ - 1797
求解1~n的最短路 (双向边)
ac code:
#include
#include
#include
#include
using namespace std;
//#define inf 0xfffffff;
const int maxn=99999999;
int map_dis[1005][1005];
bool vis[1005];
int dis[1005];
int t,n,m;
int dijkstra(int s,int k){
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++)
dis[i]=map_dis[s][i];
dis[s]=0; vis[s]=true;
for(int i=1;i<n;i++){
int u,maxx=0;
for(int j=1;j<=n;j++){
if(!vis[j]&&dis[j]>maxx){
maxx=dis[j];
u=j;
}
}
if(u==1)break;
vis[u]=true;
for(int g=1;g<=n;g++){
if(!vis[g]){
dis[g]=max(dis[g],min(dis[u],map_dis[u][g]));
}
}
}
return dis[k];
}
int main()
{
scanf("%d",&t);
for(int i=1;i<=t;i++){
memset(map_dis,0,sizeof(map_dis));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int b,e,v;
scanf("%d%d%d",&b,&e,&v);
//cout<
map_dis[b][e]=map_dis[e][b]=v;
}
printf("Scenario #");
printf("%d:\n",i);
printf("%d\n",dijkstra(1,n));
//if(i==t)
cout<<endl;
}
}
bellman:
题目链接:POJ - 3259
直接判断图内部是否有负环即可。
ac code;
//给一个无向图 并且 给一些 有向边 判断这个图中有没有 负环 如果有 时光可以倒流
//使用 bellman算法
#include
#include
#include
const int inf =0x3f3f3f3f;
const int maxn = 6000;
struct edge{
int b,e,v;
}E[maxn];
int dis [550];
bool bellman(int s,int n,int nedge)
{
for(int i=1;i<=n;i++){
dis[i]=(i==s?0:inf);
}
for(int i=1;i<n;i++){
for(int j=1;j<=nedge;j++){
if(dis[E[j].b]!=inf&&dis[E[j].e]>dis[E[j].b]+E[j].v)
dis[E[j].e]=dis[E[j].b]+E[j].v;
}
}
for(int g=1;g<=nedge;g++){
if(dis[E[g].e]>dis[E[g].b]+E[g].v){
return true;
}
}
return false;
}
int main()
{
int t,n,m,w,nnum;
scanf("%d",&t);
while(t--){
nnum=0;
scanf("%d%d%d",&n,&m,&w);
for(int i=1;i<=m;i++){
int bb,ee,vv;
scanf("%d%d%d",&bb,&ee,&vv);
E[++nnum].b=bb;E[nnum].e=ee;
E[nnum].v=vv;
E[++nnum].b=ee;E[nnum].e=bb;
E[nnum].v=vv;
}
for(int j=1;j<=w;j++){
int bb,ee,vv;
scanf("%d%d%d",&bb,&ee,&vv);
E[++nnum].b=bb;E[nnum].e=ee;
E[nnum].v=-vv;
}
if(bellman(1,n,nnum))printf("YES\n");
else printf("NO\n");
}
}
dijkstra + 优先队列优化:
题目链接:POJ - 1502
ac code:
#include
#include
#include
#include
#include
using namespace std;
const int maxn=110;
const int maxv=10050;
const int inf=0x3f3f3f3f;
int vis[maxn];
int dis[maxn];
struct edge{
int u,v,w,next;
}e[maxv];
struct node{
int dist,num;
friend bool operator < (node a,node b){
return a.dist>b.dist;
}
}p[maxn];
int head[maxn];
void init(){
memset(vis,0,sizeof(vis));
memset(dis,inf,sizeof(dis));
memset(head,-1,sizeof(head));
}
void dijkstra(int b){
priority_queue<node>q;
vis[b]=1;
dis[b]=0;
node now,temp;
now.dist=dis[b];
now.num=b;
q.push(now);
while(!q.empty()){
now=q.top();
q.pop();
vis[now.num]=0;
for(int i=head[now.num];i!=-1;i=e[i].next){
if(dis[e[i].v]>dis[now.num]+e[i].w){
dis[e[i].v]=dis[now.num]+e[i].w;
if(!vis[e[i].v]){
vis[e[i].v]=1;
temp.dist = dis[e[i].v];
temp.num = e[i].v;
q.push(temp);
}
}
}
}
}
int main()
{
int n;
int cnt=0;
scanf("%d",&n);
init();
for(int i=1;i<n;i++){
for(int j=1;j<=i;j++){
char s[10];
scanf("%s",s);
if(s[0]!='x'){
int temp=0;
int slen=strlen(s);
for(int k=0;k<slen;k++){
temp=(temp*10+(s[k]-'0'));
}
e[++cnt].u=i+1;e[cnt].v=j;
e[cnt].w=temp;e[cnt].next=head[i+1];
head[i+1]=cnt;
e[++cnt].u=j;e[cnt].v=i+1;
e[cnt].w=temp;e[cnt].next=head[j];
head[j]=cnt;
}
}
}
dijkstra(1);
int maxx=0;
for(int i=1;i<=n;i++){
//cout<
maxx=max(maxx,dis[i]);
}
printf("%d\n",maxx);
}
spfa判断负环:
题目链接:POJ - 2240
ac code :
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=50;
const int maxv=2500;
int vis[maxn];
int visitcnt[maxn];
double dis[maxn];
struct edge {
int u,v,next;
double w;
}e[maxv];
struct node{
char s[50];
int num;
}p[maxn];
int head[maxn];
void init(){
memset(vis,0,sizeof(vis));
memset(dis,0.0,sizeof(dis));
memset(visitcnt,0,sizeof(visitcnt));
}
bool spfa(int n,int b){
queue<int>q;
vis[b]=1;
dis[b]=1;
q.push(b);
while(!q.empty()){
int now=q.front();
visitcnt[now]++;
if(visitcnt[now]>n)return true;
q.pop();
vis[now]=0;
for(int i=head[now];i!=-1;i=e[i].next){
if(dis[e[i].v]<dis[now]*e[i].w){
dis[e[i].v]=dis[now]*e[i].w;
if(!vis[e[i].v]){
q.push(e[i].v);
vis[e[i].v]=1;
}
}
}
}
return false;
}
int main()
{
int n,m,tt=0;
while(scanf("%d",&n)&&n){
memset(head,-1,sizeof(head));
init();
int cnt=0;
for(int i=1;i<=n;i++){
scanf("%s",p[i].s);
p[i].num=i;
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
int u,v;
double w;
char ss[50];
scanf("%s",ss);
for(int j=1;j<=n;j++){
if(strcmp(ss,p[j].s)==0){
u=p[j].num;
break;
}
}
scanf("%lf",&w);
scanf("%s",ss);
for(int j=1;j<=n;j++){
if(strcmp(ss,p[j].s)==0){
v=p[j].num;
break;
}
}
//cout<
e[++cnt].u=u;e[cnt].v=v;
e[cnt].w=w;e[cnt].next=head[u];
head[u]=cnt;
}
bool flag=spfa(n,1);
printf("Case %d: ",++tt);
if(flag){
printf("Yes\n");
}
else{
printf("No\n");
}
}
}