POJ
慕希颜
这个作者很懒,什么都没留下…
展开
-
POJ 2251
这个题,就是个BFS,没有什么特殊的技巧可言。#include#include#include#includeusing namespace std;int l,c,r,sum;bool ans;char map[33][33][33];int vis[33][33][33];int chx[]={1,-1,0,0,0,0};int chy[]={0,0,1,-1,0,0};原创 2012-09-26 16:20:01 · 309 阅读 · 0 评论 -
POJ 2421
求最小生成树,有点不一样的是有的边已经建立好了,只要将这些建立好的边的权重设为0即可。#include#includeint n,q;int map[101][101],u[101];int prim(){ memset(u,0,sizeof(u)); int i,j,sum=0,min,now; int clost[101]; for(i=1;i clost[i]=map[1][i]; u[1原创 2013-04-22 18:41:00 · 601 阅读 · 0 评论 -
POJ 2479
求两段不相交的子段和S1、S2,使得S1+S2值最大。 这是一个典型的动态规划问题,首先正向遍历一遍求得1-i的最大子段和(注意不一定包含a[i]),然后在反向遍历一遍求得i-1的最大子段和,然后枚举划分点,求得最后的值。时间复杂度为O(n)。#include #include #include using namespace std;int dp[100001];int s[100001];原创 2013-04-22 18:41:03 · 446 阅读 · 0 评论 -
POJ 2553
求强连同分量的经典题。 if for every node w in G that is reachable from v, v is also reachable from w. 是说在v可以到达的所有点也都可以到达v,由此就可以知道求解缩点以后出度为0的点中的节点数字即可。1#include #include #include using namespace std;const int N=1原创 2013-04-22 18:41:11 · 491 阅读 · 0 评论 -
POJ 3036
一个状态就可以用到达这一状态所用的步数k、这一状态所在的x坐标、y坐标来表示。状态的目标函数自然就是到达这一状态可能的路径数。因此是一个简单的DP。#include#include#includeusing namespace std;int map[16][30][30];int main(){ memset(map,0,sizeof(map)); map[0][15][15]=1; int i原创 2013-04-22 18:41:21 · 894 阅读 · 0 评论 -
POJ 1125
【题意】:给出若干个股票经纪人以及与之有联系的其他经纪人,并给出该经纪人传播消息给与他有联系的人所需的时间,让你选出一个人作为消息的起始传播人,使得消息传播到所有经纪人耳朵里所需的时间最小。 【思路】:根据给出的每个经纪人以及传播时间可以构建出一张图,每对有联系的人之间有一条边,边的权重为传播时间,然后在这张图上求最小生成树即可。 【代码】: #include#includeus原创 2013-04-22 18:37:04 · 620 阅读 · 0 评论 -
POJ 1149
【题意】: 有 M 个猪圈(M ≤ 1000),每个猪圈里初始时有若干头猪。 一开始所有猪圈都是关闭的。 依次来了 N 个顾客(N ≤ 100),每个顾客分别会打开指定的几个猪圈,从中买若干头猪。 每个顾客分别都有他能够买的数量的上限。原创 2013-04-22 18:37:19 · 425 阅读 · 0 评论 -
POJ 1258
这是个水题哇,最小生成树哇,什么prim、克鲁斯卡尔,等等。。。 #includeint n,graph[500][500],dis[500],use[500];void prim(){ int i,j,k,m,min; int sum=0; for(i=1;i dis[i]=graph[1][i]; use[i]=1; } use[1]=0; for(i=1;i min=0x7fffff原创 2013-04-22 18:37:44 · 452 阅读 · 0 评论 -
POJ 1458
求最长公共子序列,这是一个经典的DP问题~ #include#include#includeusing namespace std;char x[1000],y[1000];int dp[1000][1000];int max(int a,int b){ if(a>b) return a; return b;}int main(){ while((scanf("%s%s",x,y))!=EOF原创 2013-04-22 18:37:54 · 498 阅读 · 0 评论 -
POJ 1651
此题求累加最小和,听说貌似是什么矩阵乘法,矩阵乘法我不太懂,反正用DP也是可以的,动态转移方程为: dp[i][j] = min(dp[i][k] + dp[k][j] + x[i] * x[k] * x[j]),i + 1 dp[i][j]表示把第i个数字到第j个数字之间(不包括i,j)的数字去光后得到的最小值,假设k是i和j之间最后取出的那张卡片。dp[1][n]就是要求的原创 2013-04-22 18:38:39 · 520 阅读 · 0 评论 -
POJ 2367
基本简单的拓扑排序。大意是:给出一个数N,下面有N行,每一行包含一些数字,以0为行尾标志,要求求出的序列每一个数排在该行行数的后面。#include#includeusing namespace std;int map[101][101];int ind[101],n,size[101];queueq;void find(){ int i,cnt; for(i=1;i if(ind[i]==0)原创 2013-04-22 18:40:46 · 522 阅读 · 0 评论 -
POJ 2386
该题为找出图中所有的连通分量,因此要把图给遍历一遍,图的遍历有DFS 和 BFS。这里用BFS的一个简单变型,被称作为flood filled 的方法。#includeusing namespace std;int dis[8][2]={-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};int sta[10000][2];char graph[100][100];int原创 2013-04-22 18:40:56 · 452 阅读 · 0 评论 -
POJ 2387
#include#includeusing namespace std;int n,t;int map[1010][1010],u[1010];int dijkstra(){ int i,j,k,Max; int dis[1010]; for(i=1;i { dis[i]=map[1][i]; u[i]=0; } u[1]=1,dis[1]=0; for(i=1;i { Max=0x7fff原创 2013-04-22 18:40:58 · 583 阅读 · 0 评论 -
POJ 2752
这个题是KMP 算法next数组的一个巧妙的使用。对于长度为len的字符串,由next的定义知:A[0]A[1]...A[next[len]-1]=A[len-next[len]]...A[len-1]此时A[0]A[1]...A[next[len]-1]为一个符合条件的前缀有A[0]A[1]....A[next[next[len]]-1] = A[len-next[next[len] - nex原创 2013-04-22 18:41:13 · 539 阅读 · 0 评论 -
POJ 2359
很显然的最小生成树的变型,用kluskal算法,首先按照每条路的权值从小到大排序,最后选取最小生成树中最长的那条路就是答案#include#include#includeusing namespace std;int n,m;long Max;int p[2010],r[2010];struct node{ int u,v; long w;};node e[10100];int cmp(node原创 2013-04-22 18:40:37 · 595 阅读 · 0 评论 -
POJ 2253
青蛙跳石头,要找到青蛙最少要能跳出去的距离,那么首先算出每对石头之间的距离,然后生成最小生成树,找到最小生成树里最长的距离,那么这个距离就是青蛙最少要能跳出去的距离。#include#include#includeint n,m;int x[201],y[201];double d[201];double map[201][201];bool u[201];void prim(){ int i,j原创 2013-04-22 18:40:29 · 443 阅读 · 0 评论 -
POJ 1961
给定一个字符串,求字符串的前几位是循环的子串,并求出循环次数。 用KMP求解,在KMP中有一个p数组记录当前字符的它的上一个位置,且保证这一段一定是来连续的。所以如果i处有循环则i到p[i]的长度即为循环节长度,所以如果i mod (i-p[i])=0则说明有循环,i div (i-p[i])就是循环次数。#include#includeusing namespace std;ch原创 2013-04-22 18:40:20 · 496 阅读 · 0 评论 -
POJ 1287
同样是一道最小生成树的题,注意连接两个节点的边可能不止一条,在读入数据的时候保留权重最小的边即可。 #include#includeusing namespace std;int p,r;int map[60][60]; int prim(){ int i,j,k; int sum=0,min; int dis[60],vis[60]; memset(vis,0,sizeof(vis))原创 2013-04-22 18:37:46 · 519 阅读 · 0 评论 -
POJ 1664
项目弄得差不多了,这几天没事看一下ACM的题也是挺不错的~【思路】: 1、当n>m时,肯定有n-m个盘子是空的,所以fun(m,n) = fun(m,n-m);2、当n (1)至少有一个盘子是空的,fun(m,n) = fun(m,n-1); (2)每个盘子都不是空的,则先从所有的苹果中拿出n个苹果,相当于先确保每个盘子都至少有一个苹果。fun(m,n) = f原创 2013-04-22 18:40:04 · 694 阅读 · 0 评论 -
POJ 1975
大小的比较有传递性,因此可以巧用求最小生成树的方法。#include#includeusing namespace std;int main(){ int i,j,k,cas,n,m; bool a[100][100]; scanf("%d",&cas); while(cas--){ scanf("%d%d",&n,&m); memset(a,0,sizeof(a)); for(i=0;i原创 2013-04-22 18:40:22 · 583 阅读 · 0 评论 -
POJ 1989
求最短非子序列的长度,找出这样的区间:该区间包含1—K的所有数字(可以有重复)。将原序列划分为N个这样的区间,则最终答案为N+1。原因是:长度为K的子序列可以由前K个区间中抽出一个数字组成,但对于K+1这样的子序列就找不到这样一个组合,因为少了最后一个数。就像例子里给的14 5 1 5 3 2 5 1 3 4 4 2 5 1 2 3 3。划分为【 5 1 5 3 2 5 1 3 4 】【 4 2原创 2013-04-22 18:40:25 · 634 阅读 · 0 评论 -
POJ 2251
这个题,就是个BFS,没有什么特殊的技巧可言。#include#include#include#includeusing namespace std;int l,c,r,sum;bool ans;char map[33][33][33];int vis[33][33][33];int chx[]={1,-1,0,0,0,0};int chy[]={0,0,1,-1,0,0};int chz[]={原创 2013-04-22 18:40:27 · 455 阅读 · 0 评论 -
POJ 1101
【题意】:给出一个地图,标有X的地方不能经过,给出一对坐标,问这对坐标能否相连通,如果能则输出最少要经过的路段(路段是指一段直线,如果中途发生转折则就是两个路段);如果不能则输出impossible。 http://poj.org/problem?id=1101 【思路】:本题较为简单,求最短路段,可用BFS解决,例外处理好地图描述的字符即可。 【注意】:本题的原创 2013-04-22 18:37:02 · 726 阅读 · 0 评论 -
POJ 1236
题意: 网络中有一些学校,每个学校可以分发软件给其他学校。可以向哪个分发取决于他们各自维护的一个清单。 有两个问题,1:至少要copy多少份新软件给那些学校, 才能使得每个学校都能得到。 2:要在所有的学校的清单里面至少一共增加几项才能 使得 把软件给任意一个学校,所有的学校都能收得到。 思路: 此题是一个有向图,求有向图的强连同分量+缩点。 先跑一边tarjan算法,缩点。 第一原创 2013-04-22 18:37:36 · 385 阅读 · 0 评论 -
POJ 1511
这个题其实是一个求最短路的问题,比较特殊的一点是汽车在返回的时候是空车返回的,那么我们就求两次最短路,第一次以节点1为起始点,第二次以节点N为起始点,将二者的结果相加就是结果。 //spaf是Bella_man算法的一个优化算法,要比Bella_man快很多 #include#include#includeusing namespace std;struct node{ int v,next;原创 2013-04-22 18:37:57 · 549 阅读 · 0 评论 -
POJ 1535
被这个题的方向弄得是晕乎乎的,索性按照常规来,注意的是面向东向右走也就是面向西往左走,所以从两头共同向前走,当从出发点走的路径到达终点时,看从终点出发的路径有木有到达起始点,如果到了则说明该条件符合要求。 #include#includeusing namespace std;int a[101][101],vis[101][101];int n,m,w,x0,y0,x1,y1;int p原创 2013-04-22 18:38:35 · 563 阅读 · 0 评论 -
POJ 1679
判断是否存在唯一的最小生成树,可以先求出一棵最小生成树的值,然后如果图边的条数大于n-1的话则可能存在不止一棵最小生成树,挨条边标记不可用看能否得到值跟原来的到一样的生成树,如果有则生成树不唯一,如果没有则生成树唯一。#include #include #include #include using namespace std;const int maxn=110;int p[110],rank[原创 2013-04-22 18:40:08 · 495 阅读 · 0 评论 -
POJ 1797
这个题就是求两点之间最长路径,将dijkstra算法中松弛那部分的“”即可。#include#includeusing namespace std;int n,m;int map[1000][1000];int vis[1000],d[1000];int min(int a,int b){ if(a>b) return b; return a;}void dijkstra(){ int i,j;原创 2013-04-22 18:40:12 · 591 阅读 · 0 评论 -
POJ 1847
这道题的关键是如何将问题转化为最短路径问题,对于从节点 i 到节点 j ,如果不需要扳动扳手则map[i][j]=0,否则map[i][j]=1,这样原问题就变为求从起点到终点的最短路问题。#include#includeint map[105][105];int n,a,b;const int Max=1000;void init(){ int i,j; for(j=1;j for(i=1;i原创 2013-04-22 18:40:14 · 500 阅读 · 0 评论 -
POJ 1861
找出最小生成树中最长的分支链路,以及输出没对节点间的距离。克鲁斯卡尔算法比较合适,因为克鲁斯卡尔算法首先按照没对节点间的距离排序,在找到最小生成树的时候最后加入生成树的那对节点间的的距离就是生成树中最长的。#include#includeusing namespace std;int pre[1001];int n,m;struct node{ int x,y,w;};node out[15001原创 2013-04-22 18:40:18 · 513 阅读 · 0 评论 -
POJ 3522
干活干累了就写个水题放松一下,此题是求所有生成树中最大边与最小边差值最小的那个值。刚好用克鲁斯卡尔很适合,将所有的边按照升序排序,然后从权重最小的边开始挨个排除,分别求出生成树里最大边跟最小边的差值,找出最小的差值。#include#include#includeusing namespace std;int n,m,cnt,pre[101];int find(int x){ while(x!=p原创 2013-04-22 18:41:25 · 620 阅读 · 0 评论