mengxm
随笔- 72  文章- 0  评论- 13 
博客园  社区  首页  新随笔  联系  管理  订阅 订阅
2012年2月22日
poj3037

只有一点转化就是一路上的速度在每一段是有变化的,但是实质上到达每一点的速度是一定的v*2^(1-h),那么也就是边权确定,可以用spfa求解,还有一点就是初始化要大,应为可以-25 <= E <= 25,也就是可能存在2^(50)这种数据。

View Code
 1 #include <stdio.h>
2 #include <string.h>
3 #include <math.h>
4 #include <queue>
5 using std::queue;
6 #define INF 11258999068426240000
7 #define MAXN 11000
8 #define clup(i,j) ((i)*(c+2)+(j))
9 struct node
10 {
11 int d,next;
12 double c;
13 }edge[5*MAXN];
14 int head[2*MAXN],p;
15 bool vis[2*MAXN];
16 double dist[2*MAXN];
17 int v,r,c,h;
18 queue <int> q;
19 void add(int a,int b,double c)
20 {
21 edge[p].d=b;
22 edge[p].c=c;
23 edge[p].next=head[a];
24 head[a]=p++;
25 }
26 void spfa()
27 {
28 vis[clup(1,1)]=true;
29 q.push(clup(1,1));
30 dist[clup(1,1)]=0;
31 int k;
32 while(!q.empty())
33 {
34 k=q.front();
35 q.pop();
36 vis[k]=false;
37 for(int i=head[k];i!=-1;i=edge[i].next)
38 if(dist[edge[i].d]>dist[k]+edge[i].c)
39 {
40 dist[edge[i].d]=dist[k]+edge[i].c;
41 if(!vis[edge[i].d])
42 {
43 vis[edge[i].d]=true;
44 q.push(edge[i].d);
45 }
46 }
47 }
48 }
49 int main()
50 {
51 //freopen("test.txt","r",stdin);
52 while(scanf("%d %d %d",&v,&r,&c)==3)
53 {
54 memset(head,-1,sizeof(head));
55 memset(vis,false,sizeof(vis));
56 p=0;
57 for(int i=1,a;i<=r;++i)
58 for(int j=1;j<=c;++j)
59 {
60 scanf("%d",&a);
61 if(i==1&&j==1) h=a;
62 add(clup(i,j),clup(i-1,j),pow(2.0,(double)(a-h))/v);
63 add(clup(i,j),clup(i,j-1),pow(2.0,(double)(a-h))/v);
64 add(clup(i,j),clup(i+1,j),pow(2.0,(double)(a-h))/v);
65 add(clup(i,j),clup(i,j+1),pow(2.0,(double)(a-h))/v);
66 }
67 for(int i=0;i<=(r+2)*(c+2);dist[i++]=INF);
68 spfa();
69 printf("%.2f\n",dist[clup(r,c)]);
70 }
71 return 0;
72 }

 

 

posted @ 2012-02-22 20:05 mengxm 阅读(22) 评论(0) 编辑
2012年2月21日
poj3169&poj1201

这两题是经典的差分约束系统,稍微学习一下就可以指导如何转化为差分约束,3169里可以看到明确的其源点1,所以求解的是从1出发终点为n的最短路,而1201则不太明显(我的代码是将其转化为最长路),但是要注意min,max在代码中的意义,和dist的定义,详情可以参考论文《数与图的完美结合--差分约束系统》,我想说的是我们要求接的是dist[max]-dist[min]的最大值,那么将dist[min]置为0然后求其到max的最大值不是更方便。

3169

View Code
 1 #include <stdio.h>
2 #include <queue>
3 #include <string.h>
4 using std::queue;
5 #define MAXN 10010
6 #define INF (1<<29)
7 struct node
8 {
9 int d,c,next;
10 }edge[2*MAXN];
11 int head[MAXN],p;
12 int dist[MAXN],cnt[MAXN];
13 int n,ml,md,max;
14 bool v[MAXN];
15 queue <int> q;
16 void add(int a,int b,int c)
17 {
18 edge[p].d=b;
19 edge[p].c=c;
20 edge[p].next=head[a];
21 head[a]=p++;
22 }
23 bool spfa()
24 {
25 dist[1]=0;
26 v[1]=true;
27 q.push(1);
28 ++cnt[1];
29 while(!q.empty())
30 {
31 int k=q.front();
32 q.pop();
33 v[k]=false;
34 for(p=head[k];p!=-1;p=edge[p].next)
35 if(dist[edge[p].d]>dist[k]+edge[p].c)
36 {
37 dist[edge[p].d]=dist[k]+edge[p].c;
38 if(!v[edge[p].d])
39 {
40 if(++cnt[edge[p].d]>n)
41 return false;
42 v[edge[p].d]=true;
43 q.push(edge[p].d);
44 }
45 }
46 }
47 return true;
48 }
49 int main()
50 {
51 //freopen("test.txt","r",stdin);
52 while(scanf("%d %d %d",&n,&ml,&md)==3)
53 {
54 memset(head,-1,sizeof(head));
55 memset(v,false,sizeof(v));
56 p=0;
57 for(int i=0,a,b,c;i<ml;++i)
58 {
59 scanf("%d %d %d",&a,&b,&c);
60 add(a,b,c);
61 }
62 for(int i=0,a,b,c;i<md;++i)
63 {
64 scanf("%d %d %d",&a,&b,&c);
65 add(b,a,-c);
66 }
67 for(int i=1;i<n;++i)
68 add(i+1,i,0);
69 for(int i=1;i<=n;dist[i++]=INF);
70 if(!spfa())
71 printf("-1\n");
72 else if(dist[n]-dist[0]>=INF)
73 printf("-2\n");
74 else
75 printf("%d\n",dist[n]-dist[0]);
76 }
77 return 0;
78 }

1201

View Code
 1 #include <stdio.h>
2 #include <string.h>
3 #include <queue>
4 using std::queue;
5 #define INF (1<<29)
6 #define MAXN 50010
7 #define MAX(a,b) ((a)>(b)?(a):(b))
8 #define MIN(a,b) ((a)<(b)?(a):(b))
9 struct node
10 {
11 int d,c,next;
12 }edge[3*MAXN];
13 int head[MAXN],p;
14 bool v[MAXN];
15 int dist[MAXN];
16 int num,max,min;
17 queue <int> q;
18 void add(int a,int b,int c)
19 {
20 edge[p].d=b;
21 edge[p].c=c;
22 edge[p].next=head[a];
23 head[a]=p++;
24 }
25 void spfa()
26 {
27 v[min]=true;
28 q.push(min);
29 dist[min]=0;
30 int k;
31 while(!q.empty())
32 {
33 k=q.front();
34 q.pop();
35 v[k]=false;
36 for(int i=head[k];i!=-1;i=edge[i].next)
37 if(dist[edge[i].d]<dist[k]+edge[i].c)
38 {
39 dist[edge[i].d]=dist[k]+edge[i].c;
40 if(!v[edge[i].d])
41 {
42 v[edge[i].d]=true;
43 q.push(edge[i].d);
44 }
45 }
46 }
47 }
48 int main()
49 {
50 //freopen("test.txt","r",stdin);
51 while(scanf("%d",&num)!=EOF)
52 {
53 memset(head,-1,sizeof(head));
54 memset(v,false,sizeof(v));
55 max=p=0;
56 min=INF;
57 for(int i=0,a,b,c;i<num;++i)
58 {
59 scanf("%d %d %d",&a,&b,&c);
60 ++b;
61 max=MAX(max,b);
62 min=MIN(min,a);
63 add(a,b,c);
64 }
65 for(int i=min;i<max;++i)
66 {
67 add(i,i+1,0);
68 add(i+1,i,-1);
69 }
70 for(int i=min;i<=max;dist[i++]=-INF);
71 spfa();
72 printf("%d\n",dist[max]-dist[min]);
73 }
74 return 0;
75 }




posted @ 2012-02-21 02:32 mengxm 阅读(55) 评论(0) 编辑
2012年2月17日
poj1364

初次尝试查分约束,遇见问题很多,总的来说这题还是比较裸地

View Code
 1 #include <stdio.h>
2 #include <string.h>
3 #include <queue>
4 using std::queue;
5 #define MAXN 110
6 #define INF (1<<29)
7 int n,m;
8 struct node
9 {
10 int d,c,next;
11 }edge[2*MAXN];
12 int head[MAXN],p,dist[MAXN],cnt[MAXN];
13 queue<int> q;
14 bool v[MAXN];
15 void addedge(int a,int b,int c)
16 {
17 edge[p].d=b;
18 edge[p].c=c;
19 edge[p].next=head[a];
20 head[a]=p++;
21 }
22 bool spfa()
23 {
24 dist[n+1]=0;
25 v[n+1]=true;
26 q.push(n+1);
27 int k;
28 while(!q.empty())
29 {
30 k=q.front();
31 q.pop();
32 v[k]=false;
33 for(p=head[k];p!=-1;p=edge[p].next)
34 if(dist[edge[p].d]>dist[k]+edge[p].c)
35 {
36 dist[edge[p].d]=dist[k]+edge[p].c;
37 if(!v[edge[p].d])
38 {
39 if((++cnt[edge[p].d])>(n+1))
40 return true;
41 q.push(edge[p].d);
42 v[edge[p].d]=true;
43 }
44 }
45 }
46 return false;
47 }
48 int main()
49 {
50 while(scanf("%d",&n),n)
51 {
52 memset(head,-1,sizeof(head));
53 memset(v,false,sizeof(v));
54 memset(cnt,0,sizeof(cnt));
55 for(int i=0;i<=n;dist[i++]=INF);
56 p=0;
57 scanf("%d",&m);
58 for(int i=0,a,b,c;i<m;++i)
59 {
60 char s[3];
61 scanf("%d %d %s %d",&a,&b,s,&c);
62 if(s[0]=='g')
63 addedge(a+b,a-1,-c-1);
64 else
65 addedge(a-1,a+b,c-1);
66 }
67 for(int i=0;i<=n;++i)
68 addedge(n+1,i,0);
69 if(spfa())
70 printf("successful conspiracy\n");
71 else
72 printf("lamentable kingdom\n");
73 }
74 return 0;
75 }



posted @ 2012-02-17 16:45 mengxm 阅读(8) 评论(0) 编辑
2012年2月16日
poj3159

SPFA:bfs形式超时,各种优化还是超时,手敲循环队列还超,伤不起啊,有木有

我必须晒晒代码,以泄我愤。

slf

View Code
 1 #include <stdio.h>
2 #include <queue>
3 using std::deque;
4 #define MAXN 150010
5 #define MAX 30010
6 #define INF (1<<29)
7 int n,m;
8 deque <int> q;
9 struct node
10 {
11 int d,t;
12 node* next;
13 }*h1[MAX],e1[MAXN],*p;
14 bool v[MAX];
15 int t[MAX];
16 void spfa()
17 {
18 for(int i=1;i<=n;++i) t[i]=INF;
19 t[1]=0;
20 q.push_back(1);
21 v[1]=true;
22 int k;
23 while(!q.empty())
24 {
25 k=q.front();
26 q.pop_front();
27 v[k]=false;
28 for(p=h1[k];p;p=p->next)
29 if(t[p->d]>t[k]+p->t)
30 {
31 t[p->d]=t[k]+p->t;
32 if(!v[p->d])
33 {
34 v[p->d]=true;
35 if(!q.empty()&&t[p->d]<t[q.front()])
36 q.push_front(p->d);
37 else
38 q.push_back(p->d);
39 }
40 }
41 }
42 }
43 int main()
44 {
45 scanf("%d %d",&n,&m);
46 p=e1;
47 for(int i=0,a,b,c;i<m;++i)
48 {
49 scanf("%d %d %d",&a,&b,&c);
50 p->d=b;
51 p->t=c;
52 p->next=h1[a];
53 h1[a]=p++;
54 }
55 spfa();
56 printf("%d\n",t[n]);
57 return 0;
58 }

手敲循环队列

View Code
 1 #include <stdio.h>
2 #define MAXN 150010
3 #define MAX 30010
4 #define INF (1<<29)
5 #define DEC(a) ((a-1+n+1)%(n+1))
6 #define INC(a) ((a+1)%(n+1))
7 int n,m;
8 struct node
9 {
10 int d,t;
11 node* next;
12 }*h1[MAX],e1[MAXN],*p;
13 bool v[MAX];
14 int t[MAX];
15 int queue[MAX],beg,end;
16 void input()
17 {
18 int a,b,c;
19 scanf("%d %d %d",&a,&b,&c);
20 p->d=b;
21 p->t=c;
22 p->next=h1[a];
23 h1[a]=p++;
24 }
25 bool empty()
26 {
27 if(end==beg)
28 return true;
29 else
30 return false;
31 }
32 int front()
33 {
34 return queue[beg];
35 }
36 void push(int a)
37 {
38 queue[end]=a;
39 end=DEC(end);
40 }
41 void pop()
42 {
43 beg=DEC(beg);
44 }
45 void spfa()
46 {
47 for(int i=1;i<=n;++i)
48 t[i]=INF,v[i]=false;
49 t[1]=0;
50 beg=end=0;
51 end=DEC(end);
52 push(1);
53 v[1]=true;
54 int k;
55 while(!empty())
56 {
57 k=front();
58 pop();
59 v[k]=false;
60 for(p=h1[k];p;p=p->next)
61 if(t[p->d]>t[k]+p->t)
62 {
63 t[p->d]=t[k]+p->t;
64 if(!v[p->d])
65 {
66 v[p->d]=true;
67 push(p->d);
68 }
69 }
70 }
71 }
72 int main()
73 {
74 scanf("%d %d",&n,&m);
75 for(int i=1;i<=n;h1[i++]=NULL);
76 p=e1;
77 for(int i=0;i<m;++i)
78 input();
79 spfa();
80 printf("%d\n",t[n]);
81 return 0;
82 }

dfs果断水过

View Code
 1 #include <stdio.h>
2 #include <stack>
3 using std::stack;
4 #define MAXN 150010
5 #define MAX 30010
6 #define INF (1<<29)
7 int n,m;
8 stack <int> q;
9 struct node
10 {
11 int d,t;
12 node* next;
13 }*h1[MAX],e1[MAXN],*p;
14 bool v[MAX];
15 int t[MAX];
16 void spfa()
17 {
18 for(int i=1;i<=n;++i) t[i]=INF;
19 t[1]=0;
20 q.push(1);
21 v[1]=true;
22 int k;
23 while(!q.empty())
24 {
25 k=q.top();
26 q.pop();
27 v[k]=false;
28 for(p=h1[k];p;p=p->next)
29 if(t[p->d]>t[k]+p->t)
30 {
31 t[p->d]=t[k]+p->t;
32 if(!v[p->d])
33 {
34 v[p->d]=true;
35 q.push(p->d);
36 }
37 }
38 }
39 }
40 int main()
41 {
42 scanf("%d %d",&n,&m);
43 p=e1;
44 for(int i=0,a,b,c;i<m;++i)
45 {
46 scanf("%d %d %d",&a,&b,&c);
47 p->d=b;
48 p->t=c;
49 p->next=h1[a];
50 h1[a]=p++;
51 }
52 spfa();
53 printf("%d\n",t[n]);
54 return 0;
55 }

泄愤归泄愤,个人觉得此题之所以dfs过的快可能是图的层数不多,但是每层节点多,所以dfs可以较快得到最优解松弛所有节点,而bfs则进行比较慢,以后若是确定最短路,且图比较稀疏,那么bfs超时的用dfs试试。


posted @ 2012-02-16 02:07 mengxm 阅读(27) 评论(0) 编辑
2012年2月15日
poj3268

dijkstra简单变形,单目标和单源最短路的结合。poj1511类似

View Code
 1 #include <stdio.h>
2 #define MAXN 100010
3 #define MAX 1010
4 #define INF (1<<29)
5 int n,m,x;
6 struct node
7 {
8 int d,t;
9 node* next;
10 }*h1[MAX],e1[MAXN],*p,*h2[MAX],e2[MAXN],*q;
11 bool v[MAX];
12 int t[MAX],sum,max[MAX];
13 void input()
14 {
15 int a,b,c;
16 scanf("%d %d %d",&a,&b,&c);
17 p->d=b;
18 p->t=c;
19 p->next=h1[a];
20 h1[a]=p++;
21 q->d=a;
22 q->t=c;
23 q->next=h2[b];
24 h2[b]=q++;
25 }
26 void dij(bool f)
27 {
28 for(int i=1;i<=n;++i)
29 {
30 v[i]=false;
31 t[i]=(i==x?0:INF);
32 }
33 int k=-1,a;
34 while(k!=INF)
35 {
36
37 k=INF;
38 for(int i=1;i<=n;++i)
39 if(!v[i]&&k>t[i])
40 k=t[i],a=i;
41 v[a]=true;
42 for(p=(f?h1[a]:h2[a]);p;p=p->next)
43 if(!v[p->d]&&t[p->d]>t[a]+p->t)
44 t[p->d]=t[a]+p->t;
45 }
46 for(int i=1;i<=n;++i)
47 max[i]+=t[i];
48 }
49 int main()
50 {
51 while(scanf("%d %d %d",&n,&m,&x)==3)
52 {
53 p=e1,q=e2;
54 for(int i=1;i<=n;++i)
55 h1[i]=h2[i]=NULL,max[i]=0;
56 for(int i=0;i<m;++i)
57 input();
58 dij(true);
59 dij(false);
60 sum=0;
61 for(int i=1;i<=n;++i)
62 sum=(sum>max[i]?sum:max[i]);
63 printf("%d\n",sum);
64 }
65 return 0;
66 }



posted @ 2012-02-15 20:59 mengxm 阅读(14) 评论(0) 编辑
poj3615

floyd水题,将map[i][j]理解为从i到j的路径中高度最小即可,将松弛条件改为map[i][j]=MIN(map[i][j],MAX(map[i][k],map[k][j]));好好理解一下吧

View Code
 1 #include <stdio.h>
2 #include <string.h>
3 #define MAXN 310
4 #define INF (1<<29)
5 #define MIN(a,b) ((a)<(b)?(a):(b))
6 #define MAX(a,b) ((a)>(b)?(a):(b))
7 int n,m,t;
8 int map[MAXN][MAXN];
9 void floyd()
10 {
11 for(int k=1;k<=n;++k)
12 for(int i=1;i<=n;++i)
13 for(int j=1;j<=n;++j)
14 map[i][j]=MIN(map[i][j],MAX(map[i][k],map[k][j]));
15 }
16 int main()
17 {
18 while(scanf("%d %d %d",&n,&m,&t)==3)
19 {
20 int a,b,c;
21 for(int i=1;i<=n;++i)
22 for(int j=1;j<=n;map[i][j++]=INF);
23 for(int i=0;i<m;++i)
24 {
25 scanf("%d %d %d",&a,&b,&c);
26 map[a][b]=c;
27 }
28 floyd();
29 for(int i=0;i<t;++i)
30 {
31 scanf("%d %d",&a,&b);
32 if(map[a][b]==INF) printf("-1\n");
33 else printf("%d\n",map[a][b]);
34 }
35 }
36 return 0;
37 }



posted @ 2012-02-15 02:33 mengxm 阅读(20) 评论(0) 编辑
2012年2月14日
poj3660
摘要: 额,应该是一道水题,只要搞清楚想要知道一只牛在什么等级就要和所有的牛都比较过也就是可以从这只牛到所有牛,那么就问题就转化为传递闭包。View Code 1 #include <stdio.h> 2 #include <string.h> 3 #define MAXN 101 4 bool map[MAXN][MAXN]; 5 int n,m; 6 void floyd() 7 { 8 for(int k=1;k<=n;++k) 9 for(int i=1;i<=n;++i)10 for(int j=1;j<=n;++j)11 ...阅读全文
posted @ 2012-02-14 23:52 mengxm 阅读(12) 评论(0) 编辑
poj2502
摘要: 好吧,我承认我水了一道题,除边计算较麻烦外。。。。==裸地dijkstraView Code 1 #include <stdio.h> 2 #include <math.h> 3 #define MAXN 210 4 #define INF (1<<29) 5 double map[MAXN][MAXN]; 6 double dist[MAXN]; 7 bool v[MAXN]; 8 int cnt; 9 struct node10 {11 double x,y;12 }p[MAXN];13 double lenth(node a,node b)14 {15阅读全文
posted @ 2012-02-14 00:52 mengxm 阅读(24) 评论(0) 编辑
2012年2月13日
poj1797
摘要: 本人一直比较愚钝,所以做题之时只有多花时间,此题是dijkstra变形,网上较多代码却少有解释为什么,我为何我一样的菜鸟来解释一下吧。首先你要明白dijkstra之所以能用贪心的原因,不明者可以看dijkstra,bellman-ford,floyd分析比较也就是dist[i]在证明中表示原点到i的最短路径,显然此题的dist表示原点到i的路径中最大载重量,为什么dist也可以表示?,当dist[i]被选中时不会改变了吗?它就是最大载重吗?如s->t最大载重是10,s->i->t最大载重是20,可能是t在i之前被选中吗?答案是不可能,若s->i->t最大载重是20阅读全文
posted @ 2012-02-13 22:59 mengxm 阅读(9) 评论(0) 编辑
2012年2月12日
poj1511
摘要: 此题结合了最短路经典变形,即将图边反向,再用单元最短路即单目标最短路,题解就是单元最短路和单目标最短路之和。有负权不可用dijkstra,看数据量和时间bellman-ford可能超时,事实证明有可能不超,用SPFA,又加了点优化用SLF。View Code 1 #include <queue> 2 #include <stdio.h> 3 #include <string.h> 4 using std::deque; 5 #define MAXN 1000010 6 #define INF (1<<30) 7 deque <int>阅读全文
posted @ 2012-02-12 17:18 mengxm 阅读(15) 评论(0) 编辑
仅列出标题  下一页
Copyright ©2012 mengxm