题目地址:
http://acm.hdu.edu.cn/showproblem.php?pid=1534
题目概述:
给出n个人之间的工作先后关系,请合理安排工作顺序满足所有条件,输出任意一组解即可。
大致思路:
题意可能没怎么讲清吧,不过工作关系第一反应其实还是网络流啦,但这个题是可以同时做多个工作的,所以得考虑别的解法了。
这里简单说一下差分约束系统,这个东西网上有很多dalao都做过总结了,我就只是说一下对于不等式 u-v<=w 则在图中从v到u连一条权值为w的有向边。
所以这题用差分约束来解决,不过题中可能有负环,所以在求最短路的时候要注意选择合理的最短路算法。其他的详见代码。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <ctime> 7 #include <map> 8 #include <stack> 9 #include <set> 10 #include <queue> 11 #include <cstring> 12 #include <algorithm> 13 using namespace std; 14 15 #define sacnf scanf 16 #define scnaf scanf 17 #define maxn 1010 18 #define maxm 35 19 #define inf 1061109567 20 #define Eps 0.000001 21 const double PI=acos(-1.0); 22 #define mod 1000000007 23 #define MAXNUM 10000 24 void Swap(int &a,int &b) {int t=a;a=b;b=t;} 25 int Abs(int x) {return (x<0)?-x:x;} 26 typedef long long ll; 27 28 struct node 29 { 30 int to,val; 31 }; 32 33 vector<node> G[maxn]; 34 char opt[10];int val[maxn],d[maxn],inq[maxn],cnt[maxn]; 35 36 void spfa(int s,int n) 37 { 38 memset(d,0x3f,sizeof(d)); 39 memset(inq,0,sizeof(inq)); 40 queue<int> q;q.push(s);inq[s]++;d[s]=0;cnt[s]++; 41 while(!q.empty()) 42 { 43 int u=q.front();q.pop(); 44 int len=G[u].size();inq[u]--; 45 if(cnt[u]>=n*100) {d[u]=inf;break;} 46 for(int i=0;i<len;i++) 47 { 48 node v=G[u][i]; 49 if(d[v.to]>d[u]+v.val) 50 { 51 d[v.to]=d[u]+v.val; 52 if(!inq[v.to]) {inq[v.to]++;q.push(v.to);cnt[v.to]++;} 53 } 54 } 55 } 56 } 57 58 int main() 59 { 60 //freopen("data.in","r",stdin); 61 //freopen("data.out","w",stdout); 62 //clock_t st=clock(); 63 int n,u,v,kase=1; 64 while(~scanf("%d",&n)) 65 { 66 if(n==0) break;G[0].clear(); 67 printf("Case %d: ",kase++); 68 for(int i=1;i<=n;i++) 69 { 70 sacnf("%d",&val[i]); 71 G[i].clear();G[0].push_back((node){i,0}); 72 } 73 while(~scanf("%s",opt)) 74 { 75 if(opt[0]=='#') break; 76 scanf("%d%d",&u,&v); 77 if(opt[0]=='F') 78 { 79 if(opt[2]=='F') G[u].push_back((node){v,val[u]-val[v]}); 80 else if(opt[2]=='S') G[u].push_back((node){v,val[u]}); 81 } 82 else if(opt[0]=='S') 83 { 84 if(opt[2]=='F') G[u].push_back((node){v,-val[v]}); 85 else if(opt[2]=='S') G[u].push_back((node){v,0}); 86 } 87 getchar(); 88 } 89 spfa(0,n);int Min=d[1],Max=d[1]; 90 for(int i=2;i<=n;i++) {Min=(Min>d[i])?d[i]:Min;Max=(Max<d[i])?d[i]:Max;} 91 if(Max==inf) {printf("impossible ");continue;} 92 if(Min>=0) Min=0;Min=-Min; 93 for(int i=1;i<=n;i++) printf("%d %d ",i,d[i]+Min); 94 printf(" "); 95 } 96 //clock_t ed=clock(); 97 //printf(" Time Used : %.5lf Ms. ",(double)(ed-st)/CLOCKS_PER_SEC); 98 return 0; 99 }
代码: