Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4641 | Accepted: 2240 |
Description
Input
Output
Sample Input
4 2 1 1 3 10 2 4 20 2 3 3
Sample Output
27
Hint
Source
/* POJ 3169 Layout 差分约束+SPFA */ //队列实现SPFA,需要有负环回路判断 #include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; const int MAXN=1010; const int MAXE=20020; const int INF=0x3f3f3f3f; int head[MAXN];//每个结点的头指针 int vis[MAXN];//在队列标志 int cnt[MAXN];//每个点的入队列次数 int que[MAXN];//SPFA循环指针 int dist[MAXN]; struct Edge { int to; int v; int next; }edge[MAXE]; int tol; void add(int a,int b,int v)//加边 { edge[tol].to=b; edge[tol].v=v; edge[tol].next=head[a]; head[a]=tol++; } bool SPFA(int start,int n) { int front=0,rear=0; for(int v=1;v<=n;v++)//初始化 { if(v==start) { que[rear++]=v; vis[v]=true; cnt[v]=1; dist[v]=0; } else { vis[v]=false; cnt[v]=0; dist[v]=INF; } } while(front!=rear) { int u=que[front++]; vis[u]=false; if(front>=MAXN)front=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(dist[v]>dist[u]+edge[i].v) { dist[v]=dist[u]+edge[i].v; if(!vis[v]) { vis[v]=true; que[rear++]=v; if(rear>=MAXN)rear=0; if(++cnt[v]>n) return false; //cnt[i]为入队列次数,用来判断是否存在负环回来 //这条好像放在这个if外面也可以?? } } } } return true; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n; int ML,MD; int a,b,c; while(scanf("%d%d%d",&n,&ML,&MD)!=EOF) { tol=0;//加边计数,这个不要忘 memset(head,-1,sizeof(head)); while(ML--) { scanf("%d%d%d",&a,&b,&c); if(a>b)swap(a,b);//注意加边顺序 add(a,b,c); //大-小<=c ,有向边(小,大):c } while(MD--) { scanf("%d%d%d",&a,&b,&c); if(a<b)swap(a,b); add(a,b,-c); //大-小>=c,小-大<=-c,有向边(大,小):-c } if(!SPFA(1,n)) printf("-1\n");//无解 else if(dist[n]==INF) printf("-2\n"); else printf("%d\n",dist[n]); } return 0; }
代码2:
/* POJ 3169 差分约束+BellmenFord */ #include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> using namespace std; const int INF=0x3f3f3f3f; const int MAXN=1010; const int MAXE=20020; int dist[MAXN]; int edge[MAXE][3];//存边 int tol;//边的总数 bool bellman(int start,int n) { for(int i=1;i<=n;i++)dist[i]=INF; dist[start]=0; for(int i=1;i<n;i++)//最多做n-1次 { bool flag=false;//优化,没有更新就跳出 for(int j=0;j<tol;j++) { int u=edge[j][0]; int v=edge[j][1]; if(dist[v]>dist[u]+edge[j][2]) { dist[v]=dist[u]+edge[j][2]; flag=true; } } if(!flag)break; } for(int j=0;j<tol;j++) if(dist[edge[j][1]] > dist[edge[j][0]]+edge[j][2]) return false; return true; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n; int ML,MD; int a,b,c; while(scanf("%d%d%d",&n,&ML,&MD)!=EOF) { tol=0; while(ML--) { scanf("%d%d%d",&a,&b,&c); if(a>b)swap(a,b); edge[tol][0]=a; edge[tol][1]=b; edge[tol][2]=c; tol++; } while(MD--) { scanf("%d%d%d",&a,&b,&c); if(a<b)swap(a,b); edge[tol][0]=a; edge[tol][1]=b; edge[tol][2]=-c; tol++; } if(!bellman(1,n))printf("-1\n"); else if(dist[n]==INF)printf("-2\n"); else printf("%d\n",dist[n]); } return 0; }