8月12号的最短路:POJ 1062&&HDU 1317
2013-08-13 19:34
239 查看
下面是算是难的了吧。。。(不知道还搞得掉吗!)
先上这个。。。
昂贵的聘礼 POJ 1062
最近比较浮躁。看了好久才懂的。。。
首先题已经知道起点!限制条件:因为有等级制度的限制。可用枚举(一个一个物品列出来)
之后发现是单向图问题!
先看代码吧。
经过三天的洗礼:终于看懂了。。。(!!!)
XYZZY HDU 1317
先讲一下题意:
有n个房间,编号1~n,小明要从1走到n。
接下给出n排:
第一个数 :到达此房间可获得的能量(100~-100) 岔口数(与哪些房间相连) 编号
注意:起点与终点获得的能量为0.初始能量为100.且每个房间只能获得一次。
因为还不知道什么是正环和负环。。。(相对于最长路与最短路来说)
首先这个题目应该求最长路吧。。。(到终点能量为正啊)
那么对应的正环就出现了,(谁会想到一开始判断1到n是否有房间连接。。。)
但是出现了正环的话,表示着什么呢?
反正求最短路时,还没遇到值为负的。。。就不清楚负环的含义。。。
看了百度百科才发现出现负环表明无最短路径。。。条件是:某点进入队列超过n次!
那么对应的正环一旦出现的话,能量对应的就为很大很大了。。。之后就判断此点到终点能不能有房间联通就行了。。。此刻就需要上面没有想到的(谁会想到一开始判断1到n是否有房间连接。。。)
那么就顺便在一开始判断1到n是否有房间连接。。。
那么关键还是理解spfa算法和负环。。。
先上这个。。。
昂贵的聘礼 POJ 1062
最近比较浮躁。看了好久才懂的。。。
首先题已经知道起点!限制条件:因为有等级制度的限制。可用枚举(一个一个物品列出来)
之后发现是单向图问题!
先看代码吧。
#include<iostream> #include<stdio.h> #include<algorithm> using namespace std; int max1,a[105][105],level[105],d[105],m,vis[105]; int distesila() { int i,min1,j,p; for(i=1;i<=m;i++) d[i]=a[0][i]; for(i=1;i<=m;i++) { min1=1000005; for(j=1;j<=m;j++) if(!vis[j]&&d[j]<min1) { min1=d[j]; p=j; } vis[p]=1;//并巧妙地和该算法已有的数组结合起来 for(j=1;j<=m;j++) { if(!vis[j]&&d[j]>d[p]+a[p][j]) d[j]=a[p][j]+d[p]; } } return d[1]; } int main() { int max1,max2,n,i,j,p,a1,a2,b2,min1level,sd; max1=10000005; while(scanf("%d%d",&n,&m)!=EOF) { for(i=0;i<=m;i++) for(j=0;j<=m;j++) a[i][j]=max1; for(i=0;i<=m;i++) a[i][i]=0; for(i=1;i<=m;i++) { scanf("%d%d%d",&p,&level[i],&a1); while(a1--) { scanf("%d%d",&a2,&b2); a[a2][i]=b2; } a[0][i]=p;//既然题目中没有明确的起点且值不会小于1的,就标志为0了 } max2=100005; for(i=1;i<=m;i++) { min1level=level[i];//假定为最小的进行枚举 for(j=1;j<=m;j++) { if(level[j]-min1level>n||level[j]<min1level) vis[j]=1;//判断并用数组进行储存该情况 else vis[j]=0; } sd=distesila(); max2=min(max2,sd); }//此处用枚举把每种可能算出来,取最小值 printf("%d\n",max2); } return 0; }
经过三天的洗礼:终于看懂了。。。(!!!)
XYZZY HDU 1317
先讲一下题意:
有n个房间,编号1~n,小明要从1走到n。
接下给出n排:
第一个数 :到达此房间可获得的能量(100~-100) 岔口数(与哪些房间相连) 编号
注意:起点与终点获得的能量为0.初始能量为100.且每个房间只能获得一次。
因为还不知道什么是正环和负环。。。(相对于最长路与最短路来说)
首先这个题目应该求最长路吧。。。(到终点能量为正啊)
那么对应的正环就出现了,(谁会想到一开始判断1到n是否有房间连接。。。)
但是出现了正环的话,表示着什么呢?
反正求最短路时,还没遇到值为负的。。。就不清楚负环的含义。。。
看了百度百科才发现出现负环表明无最短路径。。。条件是:某点进入队列超过n次!
那么对应的正环一旦出现的话,能量对应的就为很大很大了。。。之后就判断此点到终点能不能有房间联通就行了。。。此刻就需要上面没有想到的(谁会想到一开始判断1到n是否有房间连接。。。)
那么就顺便在一开始判断1到n是否有房间连接。。。
那么关键还是理解spfa算法和负环。。。
#include<iostream> #include<queue> #include<string.h> #include<algorithm> #include<stdio.h> const int MAXN=110; using namespace std; int n; int weight[MAXN]; int power[MAXN]; int _count[MAXN];//记录某点的入队列次数 bool map[MAXN][MAXN];//区分于reach[]的用法 bool reach[MAXN][MAXN];//floyd判断任何两点是否可达 void Floyd() { for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) reach[i][j]=(reach[i][j]||(reach[i][k]&&reach[k][j])); } bool SPFA(int now) { queue<int>Q; Q.push(now); memset(power,0,sizeof(power)); memset(_count,0,sizeof(_count)); power[1]=100; while(!Q.empty()) { int now=Q.front(); Q.pop(); _count[now]++; if(_count[now]>=n) return reach[now] ;//如果某个点的次数超过n次,那么说明存在正环,此时只要判断这点到n点是否可达就行了 for(int next=1;next<=n;next++) if(map[now][next]&&power[now]+weight[next]>power[next]&&power[now]+weight[next]>0)//避免有负数 { Q.push(next); power[next]=power[now]+weight[next]; } } return power >0; }//这里少了一个判断是否入列的数组,但没关系,不过时间较长一些 int main() { while(~scanf("%d",&n)&&n!=-1) { memset(map,false,sizeof(map)); memset(reach,false,sizeof(reach)); for(int i=1;i<=n;i++) { int num; scanf("%d%d",&weight[i],&num); while(num--) { int k; scanf("%d",&k); map[i][k]=true; reach[i][k]=true; } } Floyd(); if(!reach[1] )//如果起点到终点没有房间连接 printf("hopeless\n"); else { if(SPFA(1)) printf("winnable\n"); else printf("hopeless\n"); } } return 0; }
相关文章推荐
- POJ 2135 Farm Tour && HDU 2686 Matrix && HDU 3376 Matrix Again 费用流求来回最短路
- POJ 2135 Farm Tour && HDU 2686 Matrix && HDU 3376 Matrix Again 费用流求来回最短路
- poj&nbsp;1062&nbsp;昂贵的聘礼&nbsp;最短路
- POJ 3653 & ZOJ 2935 & HDU 2722 Here We Go(relians) Again(最短路dijstra)
- poj 1062 最短路
- POJ 3653 & ZOJ 2935 & HDU 2722 Here We Go(relians) Again(最短路dijstra)
- POJ 3463 && HDU 1688 Sightseeing 次短路
- 8月12号的(算是)组队赛吧。HDU 3790&&HDU 3665&&HDU 1869&&POJ 1847
- HDU 1317 && POJ 1932 &&ZJU1935 SPFA
- POJ 3835 & HDU 3268 Columbus’s bargain(最短路 Spfa)
- POJ 3835 & HDU 3268 Columbus’s bargain(最短路 Spfa)
- POJ 2388 && HDU 1157 Who's in the Middle(水~)
- 二分图的拓展与应用:HDU 2819&&POJ 1486&&HDU 3488&&HDU1853
- POJ 2195&&HDU 1533 Going Home(KM算法解决二分图最小权匹配)
- HDU 2722(POJ 3653) Here We Go(relians) Again (建图,最短路Dijstra)
- POJ 3505 && HDU 2341 Tower Parking(简单模拟)
- HDU 1874 畅通工程续【最短路 dijkstra & floyed & SPFA 】
- POJ 2909 && HDU 1397 Goldbach's Conjecture(数论)
- HDU_1455 && POJ_1011 Sticks (dfs)
- POJ 1062 昂贵的聘礼 (最短路)