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

你可能感兴趣的:(poj)