饿。。思路和实现方法与POJ 1716完全一样。。。
但根据北大那本图论书,此题应该有更加优化的建图和约束的方法,因此先丢垃圾桶。。。
#include <stdio.h> #include <string.h> #define maxn 150010 #define inf 1000000000 int head[maxn], pnt[maxn], length[maxn], next[maxn]; int tot; int dist[maxn]; int queue[10000000]; int inq[maxn]; int countq[maxn]; int n; int a,b,len; int max,min; void addedge(int a,int b, int len) { pnt[tot]=b; length[tot]=len; next[tot]=head[a]; head[a]=tot++; } int spfa(int src) { int qhead=0; int qtail=1; for(int i=min; i<=max; i++) { dist[i]=inf; inq[i]=0; countq[i]=0; } dist[src]=0; queue[qhead]=src; inq[src]=1; countq[src]++; while (qhead < qtail) { int idx=head[queue[qhead]]; while (~idx) { if(dist[pnt[idx]] > dist[queue[qhead]] +length[idx]) { dist[pnt[idx]] = dist[queue[qhead]] +length[idx]; if(!inq[pnt[idx]]) { inq[pnt[idx]]=1; countq[pnt[idx]]++; if(countq[pnt[idx]]>max-min) return 0; queue[qtail++]=pnt[idx]; } } idx=next[idx]; } inq[queue[qhead]]=0; qhead++; } return 1; } int main() { tot=0; memset(head,-1,sizeof(head)); memset(next,-1,sizeof(next)); max=0; min=inf; scanf("%d",&n); for (int i=0; i<n; i++) { scanf("%d%d%d",&a,&b,&len); addedge(b+1,a,-len); if(b+1>max) max=b+1; if(a<min) min=a; } for (int i=min; i<max; i++) { addedge(i,i+1,1); addedge(i+1,i,0); } //test /*for (int i=min; i<=max; i++) { printf("i:\n"); int idx=head[i]; while(~idx) { printf("%d %d %d\n",i,pnt[idx],length[idx]); idx=next[idx]; } }*/ spfa(max); printf("%d\n",dist[max]-dist[min]); }