poj2240_类似负权回路

题意:给出一些不同类型的货币和货币之间兑换的比例,求能否实现从一种硬币开始到自身结束后,实现盈利

分析:

1.一开始遇到这个题的时候,我首先想到的是dfs,在遍历的过程中如果遇到环的话进行判断,得出结果。但是这样考虑是不正确的。比如:

A 1.0 B
B 1.0 C
B 5.0 D
C 0.1 D
D 1.0 A
dfs时,如果先搜ABCDA是不成功的,如果这时标记搜过的D为舍弃,则ABDA就搜不到了。

2.放弃dfs后,发现这里的思路跟寻找负权回路很相似,寻找负权回路是因为在执行过程中可以不断更新,而这里如果存在盈利的话,也可以不断更新。

使用bellman-ford,必须保证图中每个点为起始点都没有回路。而使用spfa,只要看入队列次数就行

代码:

bellman-ford

View Code
  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <memory.h>
  4 #define white 0
  5 #define black 1
  6 using namespace std;
  7 //192K 32MS 
  8 //bellman-ford
  9 
 10 const int maxp=31;
 11 const int maxe=1000;
 12 struct edge
 13 {
 14     int v;
 15     double w;
 16     int next;
 17 }edge[maxe];
 18 
 19 typedef struct
 20 {
 21     double value;
 22     int color;
 23     int pre;
 24 }pp;
 25 pp point[maxp];
 26 int p,e;
 27 bool flag;
 28 
 29 void bellman_ford(int u)
 30 {
 31     point[u].value=1.0;
 32     point[u].color=black;
 33     bool f;
 34     int  i,j,k;
 35     for(k=1;k<=p-1;k++)
 36     {
 37         f=false;
 38         for(i=1;i<=p;i++)
 39             for(j=point[i].pre;j!=-1;j=edge[j].next)
 40             {
 41                 int v=edge[j].v;
 42                 point[v].color=black;
 43                 double w=edge[j].w;
 44                 if(point[v].value<point[i].value*w)
 45                 {
 46                     point[v].value=point[i].value*w;
 47                     f=true;
 48                 }
 49             }
 50         if(!f)
 51             break;
 52     }
 53     for(i=1;i<=p;i++)
 54         for(j=point[i].pre;j!=-1;j=edge[j].next)
 55             if(point[edge[j].v].value<point[i].value*edge[j].w)
 56             {
 57                 flag=false;
 58                 return ;
 59             }
 60     flag=true;
 61 }
 62 
 63 struct mode
 64 {
 65     int pp;
 66     char string[30];
 67 }mode[maxp];
 68 
 69 int find_point(char str[])
 70 {
 71     int i;
 72     for(i=1;i<=p;i++)
 73         if(strcmp(mode[i].string,str)==0)
 74             return mode[i].pp;
 75 }
 76 
 77 int main()
 78 {
 79     int i;
 80     char name[30],names[30];
 81     double t;
 82     int k=0;
 83     while(scanf("%d",&p)&& p)
 84     {
 85         k++;
 86         for(i=1;i<=p;i++)
 87         {
 88             scanf("%s",mode[i].string);
 89             mode[i].pp=i;
 90             point[i].pre=-1;
 91             point[i].color=white;
 92             point[i].value=-1.0;
 93         }
 94 
 95         scanf("%d",&e);
 96         int index=1;
 97         for(i=1;i<=e;i++)
 98         {
 99             scanf("%s%lf%s",name,&t,names);
100             int s=find_point(name);
101             int e=find_point(names);
102             edge[index].v=e;
103             edge[index].w=t;
104             edge[index].next=point[s].pre;
105             point[s].pre=index;
106             index++;
107         }
108 
109         flag=true;
110         for(i=1;i<=p;i++)
111         {
112             if(!flag)
113                 break;
114              if(point[i].color==white)
115                 bellman_ford(i);
116         }
117 
118 
119         if(!flag)
120             printf("Case %d: Yes\n",k);
121         else
122             printf("Case %d: No\n",k);
123     }
124     return 0;
125 }
126 
127 /*
128 3
129 USDollar
130 BritishPound
131 FrenchFranc
132 3
133 USDollar 0.5 BritishPound
134 BritishPound 10.0 FrenchFranc
135 FrenchFranc 0.21 USDollar
136 
137 3
138 USDollar
139 BritishPound
140 FrenchFranc
141 6
142 USDollar 0.5 BritishPound
143 USDollar 4.9 FrenchFranc
144 BritishPound 10.0 FrenchFranc
145 BritishPound 1.99 USDollar
146 FrenchFranc 0.09 BritishPound
147 FrenchFranc 0.19 USDollar
148 
149 0
150 */

spfa

View Code
  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <memory.h>
  4 #include <queue>
  5 #define white 0
  6 #define black 1
  7 using namespace std;
  8 //204K 32MS
  9 
 10 const int maxp=31;
 11 const int maxe=1000;
 12 struct edge
 13 {
 14     int v;
 15     double w;
 16     int next;
 17 }edge[maxe];
 18 
 19 typedef struct
 20 {
 21     double value;
 22     int color;
 23     int pre;
 24 }pp;
 25 pp point[maxp];
 26 int p,e;
 27 bool flag;
 28 int cnt[maxp];
 29 
 30 struct mode
 31 {
 32     int pp;
 33     char string[30];
 34 }mode[maxp];
 35 
 36 int find_point(char str[])
 37 {
 38     int i;
 39     for(i=1;i<=p;i++)
 40         if(strcmp(mode[i].string,str)==0)
 41             return mode[i].pp;
 42 }
 43 
 44 void spfa(int u)
 45 {
 46     memset(cnt,0,sizeof(cnt));
 47     queue<int> q;
 48     int t,i;
 49     q.push(u);
 50     point[u].color=black;
 51     point[u].value=1.0;
 52     cnt[u]++;
 53     while(!q.empty())
 54     {
 55         t=q.front();
 56         q.pop();
 57         point[t].color=white;
 58         for(i=point[t].pre;i!=-1;i=edge[i].next)
 59         {
 60             int v=edge[i].v;
 61             double w=edge[i].w;
 62             if(point[v].value<point[t].value*w)
 63             {
 64                 point[v].value=point[t].value*w;
 65                 if(point[v].color==white)
 66                 {
 67                     q.push(v);
 68                     point[v].color=black;
 69                     cnt[v]++;
 70                     if(cnt[v]>p)
 71                     {
 72                         flag=false;
 73                         return ;
 74                     }
 75                 }
 76             }
 77         }
 78     }
 79 }
 80 
 81 int main()
 82 {
 83     int i;
 84     char name[30],names[30];
 85     double t;
 86     int k=0;
 87     while(scanf("%d",&p)&& p)
 88     {
 89         k++;
 90         for(i=1;i<=p;i++)
 91         {
 92             scanf("%s",mode[i].string);
 93             mode[i].pp=i;
 94             point[i].pre=-1;
 95             point[i].color=white;
 96             point[i].value=-1.0;
 97         }
 98 
 99         scanf("%d",&e);
100         int index=1;
101         for(i=1;i<=e;i++)
102         {
103             scanf("%s%lf%s",name,&t,names);
104             int s=find_point(name);
105             int e=find_point(names);
106             edge[index].v=e;
107             edge[index].w=t;
108             edge[index].next=point[s].pre;
109             point[s].pre=index;
110             index++;
111         }
112 
113         flag=true;
114         spfa(1);
115 
116         if(!flag)
117             printf("Case %d: Yes\n",k);
118         else
119             printf("Case %d: No\n",k);
120     }
121     return 0;
122 }
123 /*
124 3
125 USDollar
126 BritishPound
127 FrenchFranc
128 3
129 USDollar 0.5 BritishPound
130 BritishPound 10.0 FrenchFranc
131 FrenchFranc 0.21 USDollar
132 
133 3
134 USDollar
135 BritishPound
136 FrenchFranc
137 6
138 USDollar 0.5 BritishPound
139 USDollar 4.9 FrenchFranc
140 BritishPound 10.0 FrenchFranc
141 BritishPound 1.99 USDollar
142 FrenchFranc 0.09 BritishPound
143 FrenchFranc 0.19 USDollar
144 
145 0
146 */

 这个题还可以用floyd做,因为没有确定的源点,最终求出arrray[i][i],如果大于初始值1,则yes,否则no

tjuoj 1129

posted @ 2012-08-28 17:43  pushing my way  阅读(439)  评论(0编辑  收藏  举报