hdu 1317+hdu 1535(SPFA)
2014-05-26 17:55
197 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1317
思路:只要在SPFA中将一个条件,就不会进入负环。那么如果有正环呢,显然退出条件是某个点入队列次数>=n,此时退出时只需判断当前点是否与n存在路径,这步可以用Floyd来实现。。。
View Code
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1535
思路:正向建一次图,反向建一次图,然后两次SPFA就可以了,采用vector的邻接表形式,特别好用。。。
View Code
思路:只要在SPFA中将一个条件,就不会进入负环。那么如果有正环呢,显然退出条件是某个点入队列次数>=n,此时退出时只需判断当前点是否与n存在路径,这步可以用Floyd来实现。。。
View Code
1 #include<iostream> 2 #include<queue> 3 const int MAXN=110; 4 using namespace std; 5 int n; 6 int weight[MAXN]; 7 int power[MAXN]; 8 int _count[MAXN];//记录某点的入队列次数 9 bool map[MAXN][MAXN]; 10 bool reach[MAXN][MAXN];//floyd判断任何两点是否可达 11 12 13 void Floyd(){ 14 for(int k=1;k<=n;k++){ 15 for(int i=1;i<=n;i++){ 16 for(int j=1;j<=n;j++){ 17 reach[i][j]=(reach[i][j] 18 ||(reach[i][k]&&reach[k][j])); 19 } 20 } 21 } 22 } 23 24 bool SPFA(int now){ 25 queue<int>Q; 26 Q.push(now); 27 memset(power,0,sizeof(power)); 28 memset(_count,0,sizeof(_count)); 29 power[1]=100; 30 while(!Q.empty()){ 31 int now=Q.front(); 32 Q.pop(); 33 _count[now]++; 34 if(_count[now]>=n)return reach[now] ;//如果某个点的次数超过n次,那么说明存在正环,此时只要判断这点到n点是否可达就行了 35 for(int next=1;next<=n;next++){ 36 if(map[now][next]&&power[now]+weight[next]>power[next] 37 &&power[now]+weight[next]>0){ 38 Q.push(next); 39 power[next]=power[now]+weight[next]; 40 } 41 } 42 } 43 return power >0; 44 } 45 46 int main(){ 47 while(~scanf("%d",&n)&&n!=-1){ 48 memset(map,false,sizeof(map)); 49 memset(reach,false,sizeof(reach)); 50 for(int i=1;i<=n;i++){ 51 int num; 52 scanf("%d%d",&weight[i],&num); 53 for(int j=1;j<=num;j++){ 54 int k; 55 scanf("%d",&k); 56 map[i][k]=true; 57 reach[i][k]=true; 58 } 59 } 60 Floyd(); 61 if(!reach[1] ){ 62 printf("hopeless\n"); 63 }else { 64 if(SPFA(1)){ 65 printf("winnable\n"); 66 }else 67 printf("hopeless\n"); 68 } 69 } 70 return 0; 71 }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1535
思路:正向建一次图,反向建一次图,然后两次SPFA就可以了,采用vector的邻接表形式,特别好用。。。
View Code
1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 const int MAXN=1000000+10; 5 typedef long long ll; 6 const ll inf=1e60; 7 using namespace std; 8 struct Node{ 9 int v,w; 10 }; 11 vector<Node>mp1[MAXN];//正向建图 12 vector<Node>mp2[MAXN];//反向建图 13 int n,m; 14 ll cost[MAXN]; 15 16 void SPFA(int u,vector<Node>mp[]){ 17 for(int i=2;i<=n;i++)cost[i]=inf; 18 cost[1]=0; 19 queue<int>Q; 20 Q.push(u); 21 while(!Q.empty()){ 22 int u=Q.front(); 23 Q.pop(); 24 for(int i=0;i<mp[u].size();i++){ 25 int v=mp[u][i].v; 26 int w=mp[u][i].w; 27 if(cost[v]>cost[u]+w){ 28 cost[v]=cost[u]+w; 29 Q.push(v); 30 } 31 } 32 } 33 } 34 35 36 int main(){ 37 int _case; 38 scanf("%d",&_case); 39 while(_case--){ 40 scanf("%d%d",&n,&m); 41 for(int i=1;i<=n;i++){ 42 mp1[i].clear(); 43 mp2[i].clear(); 44 } 45 for(int i=1;i<=m;i++){ 46 int u,v,w; 47 scanf("%d%d%d",&u,&v,&w); 48 Node p1,p2; 49 p1.v=u,p2.v=v,p1.w=p2.w=w; 50 mp1[u].push_back(p2); 51 mp2[v].push_back(p1); 52 } 53 SPFA(1,mp1);//正向求一次 54 ll ans=0; 55 for(int i=2;i<=n;i++){ 56 ans+=cost[i]; 57 } 58 SPFA(1,mp2);//反向求一次 59 for(int i=2;i<=n;i++){ 60 ans+=cost[i]; 61 } 62 printf("%lld\n",ans); 63 } 64 return 0; 65 } 66 67
相关文章推荐
- hdu 1317+hdu 1535(SPFA)
- [HDU 1317]XYZZY[SPFA变形][最长路]
- HDU 1535 Invitation Cards SPFA
- HDU 1535 SPFA 前向星存图优化
- HDU 1535 Invitation Cards【SPFA最短路】【正反向建边求单源最短路之和】
- HDU 1317--XYZZY 【spfa判断正环求最长路径 && floyd求传递闭包】
- HDU 1535 Invitation Cards(多源点到单源点,dijkstra/spfa)
- 【SPFA邻接表】HDU 1535 Invitation Cards
- hdu 1317 XYZZY(spfa判环)
- hdu 1535 Invitation Cards(spfa)
- HDU 1535 Invitation Cards 有向图的来回最短路(邻接表反向建图)+spfa
- HDU 1317 XYZZY (SPFA 找正环 + Floyd 判连通)
- HDU 1317(Floyd判断连通性+spfa判断正环)
- hdu 1317 SPFA+连通判断+最长路
- hdu 1535 Invitation Cards(spfa)
- HDU 1317(spfa找环)
- HDU 1317/POJ 1932 Floyd + Spfa 最长路
- HDU 1535 Invitation Cards (最短路,附SLF优化SPFA)
- hdu 1535 Invitation Cards【SPFA】
- [HDU 1317]XYZZY[SPFA变形][最长路]