# spfa算法的优化及应用 poj 2949

（E1- Ans）+（E2- Ans）+….+ （Ek- Ans）>0

View Code
#include<cstdio>
#include<map>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1010;
const int M = 100010;
const double eps = 1e-3;
const double inf = 1000000000;
struct EDGE{
int v,next;
double w;
}edge[M],TE[M];
int E,tot;
stack<int> ST;
edge[E].v=b;
edge[E].w=w;
}
bool vis[N];
double dis[N];
int in[N];
bool PC;//正环
double MaxEdge;
void spfa(double aver,int n){
while(!ST.empty()) ST.pop();
fill(vis,vis+n+1,false);
fill(dis,dis+n+1,0);
fill(in,in+n+1,0);
for(int i=1;i<=n;i++)  ST.push(i),vis[i]=true;
while(!ST.empty()){
int u=ST.top();ST.pop();vis[u]=false;
int v=edge[i].v;
if(dis[u]+edge[i].w-aver>dis[v]){
dis[v]=dis[u]+edge[i].w-aver;
if(dis[v]>MaxEdge){ PC=true;return ;}
if(!vis[v]){
vis[v]=true;
ST.push(v);
in[v]++;
if(in[v]>n+1){
PC=true;
return ;
}
}
}
}//end of for
}// end of while
}
bool solve(double aver){
PC=false;
spfa(aver,tot);
return PC;
}
char s[M];
int flag[3010];
int main(){
int n;
while(scanf("%d",&n),n){
E=0;tot=0;MaxEdge=0;
fill(flag,flag+3000,0);
for(int i=0;i<n;i++){
scanf("%s",s);
int len=strlen(s);
if(len>MaxEdge) MaxEdge=len;
int a=(s[0]-'a')*26+s[1]-'a';
int b=(s[len-2]-'a')*26+s[len-1]-'a';
if(!flag[a])  flag[a]=++tot;
int id1=flag[a];
if(!flag[b])  flag[b]=++tot;
int id2=flag[b];
}
MaxEdge*=n;
double l=0,r=1000,best=-1,mid;
while(l+eps<=r){
mid=(l+r)/2;
if(solve(mid)){
best=mid;
l=mid;
}
else r=mid;
}
if(best!=-1) printf("%.3lf\n",best);
else printf("No solution.\n");
}
return 0;
}

View Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 677;
const int M = 100010;
const double eps = 1e-3;
const double inf = 1000000000;
struct EDGE{
int v,next;
double w;
}edge[M],TE[M];
edge[E].v=b;
edge[E].w=w;
}
int vis[N];
double dis[N];
int in[N];
bool PC;//正环
double MaxEdge,aver;
void spfa(int u,int h,double aver){
if(PC) return ;
vis[u]=h;
int v=edge[i].v;
if(dis[u]+edge[i].w-aver>dis[v]){
dis[v]=edge[i].w+dis[u]-aver;
if(dis[v]>MaxEdge) {PC=true;return ;}
if(!vis[v]) spfa(v,h,aver);if(PC) return ;
else if(vis[v]==h){
PC=true;
return ;
}
}
}
vis[u]=0;
}
bool solve(double aver){
PC=false;
fill(dis,dis+tot+1,0);
fill(vis,vis+tot+1,0);
for(int i=1;i<=tot;i++){
spfa(i,i,aver);
if(PC) break;
}
return PC;
}
char s[M];
int flag[800];
int main(){
int n;
while(scanf("%d",&n),n){
E=0;tot=0;MaxEdge=0;
fill(flag,flag+700,0);
for(int i=0;i<n;i++){
scanf("%s",s);
int len=strlen(s);
if(len>MaxEdge) MaxEdge=len;
int a=(s[0]-'a')*26+s[1]-'a';
int b=(s[len-2]-'a')*26+s[len-1]-'a';
if(!flag[a])  flag[a]=++tot;
int id1=flag[a];
if(!flag[b])  flag[b]=++tot;
int id2=flag[b];
}
MaxEdge*=n;
double l=0,r=1000,best=-1,mid;
while(l+eps<r){
mid=(l+r)/2;
if(solve(mid)){
best=mid;
l=mid;
}
else r=mid;
}
if(best!=-1) printf("%.3f\n",best);
else printf("No solution.\n");
}
return 0;
}
posted @ 2012-07-13 17:28 Because Of You Views(...) Comments(...) Edit 收藏