差分约数:
求满足不等式条件的尽量小的值---->求最长路---->a-b>=c----> b->a (c)
3 2 3 4 SAF 2 1 FAF 3 2 # 3 1 1 1 SAF 2 1 SAF 3 2 SAF 1 3 # 0
Case 1: 1 0 2 2 3 1 Case 2: impossible
/* *********************************************** Author :CKboss Created Time :2015年07月29日 星期三 16时20分17秒 File Name :HDOJ1534.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> using namespace std; const int maxn=5000; int n; int w[maxn]; struct Edge { int to,next,cost; }edge[maxn]; int Adj[maxn],Size; void init() { memset(Adj,-1,sizeof(Adj)); Size=0; } void Add_Edge(int u,int v,int c) { edge[Size].to=v; edge[Size].cost=c; edge[Size].next=Adj[u]; Adj[u]=Size++; } void SAF(int u,int v) { Add_Edge(v,u,w[v]); } void SAS(int u,int v) { Add_Edge(v,u,0); } void FAF(int u,int v) { Add_Edge(v,u,w[v]-w[u]); } void FAS(int u,int v) { Add_Edge(v,u,-w[u]); } /// spfa longest road int dist[maxn],cq[maxn]; bool inq[maxn]; bool spfa() { memset(dist,0xcf,sizeof(dist)); memset(cq,0,sizeof(cq)); memset(inq,false,sizeof(inq)); dist[0]=0; queue<int> q; inq[0]=true; q.push(0); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=Adj[u];~i;i=edge[i].next) { int v=edge[i].to; if(dist[v]<dist[u]+edge[i].cost) { dist[v]=dist[u]+edge[i].cost; if(!inq[v]) { inq[v]=true; cq[v]++; if(cq[v]>=n) return false; q.push(v); } } } inq[u]=false; } return true; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int cas=1; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) scanf("%d",w+i); init(); char cmd[20]; while(scanf("%s",cmd)!=EOF) { if(cmd[0]=='#') break; int u,v; scanf("%d%d",&u,&v); if(strcmp(cmd,"SAF")==0) { SAF(u,v); } else if(strcmp(cmd,"FAF")==0) { FAF(u,v); } else if(strcmp(cmd,"FAS")==0) { FAS(u,v); } else if(strcmp(cmd,"SAS")==0) { SAS(u,v); } } for(int i=1;i<=n;i++) Add_Edge(0,i,0); bool fg=spfa(); printf("Case %d:\n",cas++); if(fg==false) { puts("impossible"); } else { int mx=0; for(int i=1;i<=n;i++) { if(dist[i]<mx) mx=dist[i]; } for(int i=1;i<=n;i++) { printf("%d %d\n",i,dist[i]-mx); } } putchar(10); } return 0; }