想看更多的解题报告: http://iyenn.com/rec/1824570.html
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:给出n个点m个约束
如果约束是P a b c的形式就代表,a在b北边的c的位置
如果约束是V a b 的形式就代表,a在b北边1或者更远的位置。
解题思路:很明显,我们由题目可以得到不等式
首先设d[i]为从初始点到i点的距离
V a b ----> d[a]-d[b]>=1
P a b c ----> d[a]-d[b]==c
那么根据上两个式子分析,再得到:
V:d[b]-d[a]<=-1
P:d[a]-d[b]<=c 因为等号可以化成两个不等式
d[a]-d[b]>=c
这样最后得到:
V:d[b]-d[a]<=-1
P:d[a]-d[b]<=c
d[b]-d[a]<=-c
这样根据约束用bellman_ford直接可以做,不过spfa还有点不一样
如果用spfa的话,所有的点不一定会互相连通的,这样我们设一个虚点(随便什么点)与其他所有点相连,不过长度为0
for(i=1;i<=n;i++) add(s,i,0);
这个地方不要看成了是不等式,他只是消掉了自身的负环而已
当然这里我设s为0,为其他的也可以
- /*
- spfa
- Memory 2564K
- Time 610MS
- */
- #include
- #include
- using namespace std;
- #define MAXE 250000
- #define MAXV 1010
- #define INF INT_MAX
-
- typedef struct{
- int t,w,next;
- }Edge;
-
- Edge edge[MAXE];
-
- int n,m,edgesum,d[MAXV];
- int headlist[MAXV],sum[MAXV];
- bool vis[MAXV];
-
- void add(int s,int t,int w){
- edge[edgesum].t=t;
- edge[edgesum].next=headlist[s];
- edge[edgesum].w=w;
- headlist[s]=edgesum++;
- }
-
- bool spfa(){
- queue <int>q;
- int i,v,u;
- memset(sum,0,sizeof(sum));
- memset(vis,false,sizeof(vis));
- for(i=1;i<=n;i++) d[i]=INF;
-
- d[0]=0;
- vis[0]=true;
- q.push(0);
- while(!q.empty()){
- v=q.front();q.pop();
- vis[v]=false;
-
- if(++sum[v]>n) return 0; //有负环返回false
-
- for(i=headlist[v];i!=-1;i=edge[i].next){
- u=edge[i].t;
- if(d[v]+edge[i].w
- d[u]=d[v]+edge[i].w;
- if(!vis[u]){
- q.push(u);
- vis[u]=true;
-
- }
- }
- }
- }
-
- return 1;
- }
-
- int main(){
- int i,a,b,c;
- char ch;
- while(~scanf("%d%d\n",&n,&m)){
- edgesum=0;
- memset(headlist,-1,sizeof(headlist));
- for(i=0;i
- scanf("%c%d%d",&ch,&a,&b);
- if(ch=='P'){
- scanf("%d",&c);
- add(a,b,-c);
- add(b,a,c);
- }else{
- add(a,b,-1);
- }
- getchar();
- }
-
- for(i=1;i<=n;i++) add(0,i,0); //消掉自身的负环
-
- if(spfa()) printf("Reliable\n");
- else printf("Unreliable\n");
- }
- return 0;
- }
===========================================================
- /*
- bellman_ford
- Memory 2516K
- Time 454MS
- */
- #include
- using namespace std;
- #define MAXE 200000
- #define MAXV 1010
-
- typedef struct{
- int s,t,w;
- }Edge;
-
- Edge edge[MAXE];
-
- int n,m,edgesum,d[MAXV];
-
- void add(int s,int t,int w){
- edge[edgesum].s=s;
- edge[edgesum].t=t;
- edge[edgesum++].w=w;
- }
-
- bool bellman_ford(){
- int j,cnt=0;
- memset(d,0,sizeof(d));
-
- bool flag=true;
- while(flag && cnt<=n){
- flag=false;
- cnt++;
- for(j=0;j
- if(d[edge[j].s]+edge[j].w
- d[edge[j].t]=d[edge[j].s]+edge[j].w;
- flag=true;
- }
- }
-
- if(cnt
return 1; - return 0;
- }
-
- int main(){
- int i,a,b,c;
- char ch;
- while(~scanf("%d%d\n",&n,&m)){
- edgesum=0;
- for(i=0;i
- scanf("%c%d%d",&ch,&a,&b);
- if(ch=='P'){
- scanf("%d",&c);
- add(a,b,-c);
- add(b,a,c);
- }else{
- add(a,b,-1);
- }
- getchar();
- }
-
- if(bellman_ford()) printf("Reliable\n");
- else printf("Unreliable\n");
- }
- return 0;
- }
评论记录:
回复评论: