1. poj 1502 Mathches Game

  裸最短路

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <math.h> #define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = ;
const int maxn = ; struct edge {
int to, next, val;
}e[maxn*maxn]; int dis[maxn], linjie[maxn];
bool vis[maxn];
int N, cnt, ans; void addedge( int x, int y, int val )
{
e[cnt].to = y; e[cnt].next = linjie[x]; e[cnt].val = val; linjie[x] = cnt++; } void init()
{
cnt = ans = ;
memset( linjie, -, sizeof(linjie) );
memset( dis, 0x3f, sizeof(dis) );
memset( vis, , sizeof(vis) );
} void read()
{
init();
string str;
int tmp = ; for ( int i = ; i < N; i++ )
{
for ( int j = ; j < tmp; j++ )
{
int val = ;
cin >> str; if ( str == "x" )
continue;
int len = str.length(); int x = ;
for ( int k = len - ; k >= ; k-- )
{
val += (str[k]-'')*x;
x *= ;
}
addedge( i, j, val );
addedge( j, i, val );
}
tmp++;
}
} void dijkstra()
{
dis[] = ; for ( int i = ; i < N; i++ )
{
int mindis = inf, mark = -;
for ( int j = ; j < N; j++ )
if ( !vis[j] && dis[j] < mindis )
{
mark = j;
mindis = dis[j];
} vis[mark] = true; for ( int j = linjie[mark]; j+; j = e[j].next )
if (!vis[e[j].to])
{
int v = e[j].to, val = e[j].val;
dis[v] = Min(dis[v], dis[mark]+val);
}
}
} int main()
{
cin >> N; read();
dijkstra(); for ( int i = ; i < N; i++ )
ans = Max( ans, dis[i] ); cout << ans << endl;
return ;
}

2. poj 3660 cow contest

  floyd 求传递闭包

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <math.h> #define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = ;
const int maxn = ; bool mmap[maxn][maxn];
int ojbk[maxn];
int N, M; void floyd()
{
for ( int k = ; k <= N; k++ )
for ( int i = ; i <= N; i++ )
for ( int j = ; j <= N; j++ )
{
mmap[i][j] = (mmap[i][j] || (mmap[i][k] && mmap[k][j]));
}
} int main()
{
cin >> N >> M; int x, y;
for ( int i = ; i <= M; i++ )
{
scanf("%d %d", &x, &y);
mmap[x][y] = ;
} floyd(); int ans = ;
for ( int i = ; i <= N; i++ )
for ( int j = ; j <= N; j++ )
if ( mmap[i][j] )
{
ojbk[i]++;
ojbk[j]++;
} for ( int i = ; i <= N; i++ )
if ( ojbk[i] == N- )
ans++;
cout << ans << endl; return ;
}

3. poj 1511 Invitation Cards

  双向最短路,正着求一次,边取反再求一次

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <math.h> #define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = ;
const int maxn = 1e6+; int num[*maxn];
int linjie[maxn];
int dis[maxn];
bool vis[maxn];
int P, Q, cnt;
long long ans; struct edge {
int to, next, val ;
}e[maxn]; struct cmp {
bool operator() ( const int a, const int b )
{ return dis[a]>dis[b]; }
}; void addedge( int u, int v, int val )
{ e[cnt].to = v; e[cnt].next = linjie[u]; e[cnt].val = val; linjie[u] = cnt++; } void init()
{
cnt = ; ans = ;
memset( linjie, -, sizeof(linjie) );
} void dijkstra()
{
memset( dis, 0x3f, sizeof(dis) );
memset( vis, , sizeof(vis) ); priority_queue<int, vector<int>, cmp> q;
dis[] = ;
q.push(); while (!q.empty())
{
int run = q.top(); q.pop();
int mindis = dis[run]; vis[run] = true; for ( int i = linjie[run]; i+; i = e[i].next )
if ( !vis[e[i].to] && dis[e[i].to] > mindis + e[i].val )
{
dis[e[i].to] = mindis + e[i].val;
q.push(e[i].to);
}
}
for ( int i = ; i <= P; i++ )
ans += (long long)dis[i];
} int main()
{
int n;
cin >> n; while (n--)
{
init();
scanf( "%d %d", &P, &Q ); int j = ;
for ( int i = ; i <= Q; i++ )
{
scanf( "%d %d %d", &num[j], &num[j+], &num[j+] );
addedge( num[j], num[j+], num[j+] );
j += ;
}
dijkstra(); //重新建边///
memset( linjie, -, sizeof(linjie) );
cnt = ; j = ;
for ( int i = ; i <= Q; i++ )
{
addedge( num[j+], num[j], num[j+] );
j += ;
} dijkstra(); printf( "%lld\n", ans );
} return ;
}

4.poj 3159 Candies

  dijsktra+优先队列优化+差分约束

 #include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <vector>
#define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = + ;
const int maxn = + ; int linjie[maxn];
int dis[maxn];
bool vis[maxn];
int P, Q, cnt; struct qnode
{
int v;
int c;
qnode(int _v=,int _c=):v(_v),c(_c){}
bool operator <(const qnode &r)const
{
return c>r.c;
}
}; struct edge {
int to, next, val ;
}e[maxk]; void addedge( int u, int v, int val )
{ e[cnt].to = v; e[cnt].next = linjie[u]; e[cnt].val = val; linjie[u] = cnt++; } void init()
{
cnt = ;
memset( linjie, -, sizeof(linjie) );
} void dijkstra()
{
memset( dis, 0x3f, sizeof(dis) );
memset( vis, , sizeof(vis) ); priority_queue<qnode> q;
while(!q.empty()) q.pop();
dis[] = ;
q.push(qnode(,)); qnode tmp; while (!q.empty())
{
tmp = q.top(); q.pop();
int run = tmp.v;
int mindis = dis[run]; vis[run] = true; for ( int i = linjie[run]; i+; i = e[i].next )
if ( !vis[e[i].to] && dis[e[i].to] > mindis + e[i].val )
{
int v = e[i].to;
dis[v] = mindis + e[i].val;
q.push(qnode(v, dis[v]));
}
}
} int main()
{
init();
scanf( "%d%d", &P, &Q ); int x, y, z;
for ( int i = ; i <= Q; i++ )
{
scanf( "%d%d%d", &x, &y, &z );
addedge(x,y,z);
} dijkstra(); printf( "%d\n", dis[P] ); return ;
}

5. poj 3169 Layout

  spfa+负环+差分约束

  最经典的差分约束,因为求的是dis[N]-dis[1]的最大值 ,即dis[N]-dis[1] <= x,所以用最短路。用spfa判断若有负环,说明最短路无限小,所以无解;若dis[N] = inf,说明最短路可以无限大,

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <math.h> #define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = 2e4+;
const int maxn = ; int N, Ml, Md, cnt;
int linjie[maxn], in[maxn];
bool vis[maxn];
long long dis[maxn]; struct edge {
int to, next, val;
}e[maxk]; void addedge( int u, int v, int val )
{
e[cnt].to = v;
e[cnt].next = linjie[u];
e[cnt].val = val;
linjie[u] = cnt++;
} void init()
{
cnt = ;
memset( linjie, -, sizeof(linjie) );
} long long spfa()
{
memset( dis, 0x3f, sizeof(dis) ); queue<int> q;
q.push(); dis[] = ; while ( !q.empty() )
{
int run = q.front(); q.pop();
vis[run] = false; for ( int i = linjie[run]; i+; i = e[i].next )
{
int v = e[i].to, cost = e[i].val;
if ( dis[v] > dis[run] + cost )
{
dis[v] = dis[run] + cost;
if (!vis[v])
{
in[v]++;
if ( in[v] > N ) return -; vis[v] = true;
q.push(v);
}
}
}
} if ( dis[N] == INF ) return -;
else
return dis[N];
} int main()
{
init();
cin >> N >> Ml >> Md; //差分约束条件建边
int a, b, z;
for ( int i = ; i <= Ml; i++ )
{ scanf("%d%d%d", &a, &b, &z); addedge(a,b,z); }
for ( int i = ; i <= Md; i++ )
{ scanf("%d%d%d", &a, &b, &z); addedge(b,a,-z); } printf( "%lld\n", spfa() );
return ;
}

6. hdu3416 Marriage Match IV

  dijkstra+最大流dinic当前弧优化

  hdu的题好难...这题最不一样的是求一共有多少条最短路(路径不可以重复),一个暴力的想法就是求一条最短路再删去该路的所有边,再求最短路,再删边,直到求得最短路长度大于第一次求得的长度为止,不过用脚趾头想都知道数据肯定会卡你的。

其实会发现如果抛弃最短路来看,这道题很像最大流,就是所有边权为1求最大流的题目,不过现在加了约束条件必须在最短路上取最大流。所以我们可以求出所有的最短路径的边并重新建一个边权为1的图,在其上做最大流就可以了,那么怎么求所有最短路径呢?

有个方法是从终点dijkstra一下再从起点dijkstra下(注意要建立反向边图),假设dis1[u]表示start-u之间最短距离,dis2[v]表示v-end之间最短距离,那么只要dis1[u]+dis2[v]+dis[u][v] == 最短路长度,就代表这条边是可以要的

 #include <iostream>
#include <string.h>
#include <cstdio>
#include <queue>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <math.h> #define SIGMA_SIZE 26
#pragma warning ( disable : 4996 ) using namespace std;
typedef long long LL; inline LL LMax(LL a,LL b) { return a>b?a:b; }
inline LL LMin(LL a,LL b) { return a>b?b:a; }
inline int Max(int a,int b) { return a>b?a:b; }
inline int Min(int a,int b) { return a>b?b:a; }
inline int gcd( int a, int b ) { return b==?a:gcd(b,a%b); }
inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int mod = ;
const int maxk = 1e5+;
const int maxn = ; int N, M, cnt;
int st, ed;
int num[maxk*];
int disst[maxn], dised[maxn], cur[maxn];
int linjie1[maxn], linjie2[maxn];
bool vis[maxn]; struct node {
int to, next, val;
}e1[maxk], e2[maxk]; void addedge1( int u, int v, int val )
{ e1[cnt].to = v; e1[cnt].val = val; e1[cnt].next = linjie1[u]; linjie1[u] = cnt++; }
void addedge2( int u, int v, int val )
{ e2[cnt].to = v; e2[cnt].val = val; e2[cnt].next = linjie2[u]; linjie2[u] = cnt++; } void init()
{
cnt = ;
memset( linjie1, -, sizeof(linjie1) );
memset( linjie2, -, sizeof(linjie2) );
} void dijkstra( int x )
{
memset( vis, , sizeof(vis) );
memset( disst, 0x3f, sizeof(disst) );
disst[x] = ; for ( int k = ; k <= N; k++ )
{
int mark = -, mindis = inf;
for ( int i = ; i <= N; i++ )
if ( !vis[i] && disst[i] < mindis )
{
mark = i;
mindis = disst[i];
}
vis[mark] = true; for ( int i = linjie1[mark]; i+; i = e1[i].next )
{
int v = e1[i].to, cost = e1[i].val;
if ( !vis[v] && disst[v] > disst[mark] + cost )
disst[v] = disst[mark] + cost;
}
}
} void make_map()
{
cnt = ;
int mindist = disst[ed]; for ( int i = ; i <= N; i++ )
for ( int j = linjie1[i]; j + ; j = e1[j].next )
{
int v = e1[j].to, cost = e1[j].val;
if ( disst[i] + cost + dised[v] == mindist )
addedge2( i, v, );
}
} int bfs()
{
memset( disst, -, sizeof(disst) );
queue<int> q; q.push(st);
disst[st] = ; while( !q.empty() )
{
int run = q.front(); q.pop();
for( int i = linjie2[run]; i+; i = e2[i].next )
{
int v = e2[i].to, flow = e2[i].val;
if( disst[v] < && flow > )
{
disst[v] = disst[run] + ;
q.push(v);
}
}
} if( disst[ed] > )
return ;
else
return ;
} int find( int s, int low )
{
int ff = ;
if( s == ed )
return low;
for( int& i = cur[s]; i+; i = e2[i].next ) //注意int& i = cur[s] 当前弧优化
{
int v = e2[i].to, cap = e2[i].val;
if( cap >
&& disst[v] == disst[s] +
&& (ff = find(v,Min(cap,low))) )
{
e2[i].val -= ff;
//e2[i^1].val += ff;
return ff;
}
}
return ;
} int dinic()
{
int ans = ;
int tans;
while( bfs() )
{
for( int i = ; i <= N; i++ ) //当前弧优化
cur[i] = linjie2[i];
while( tans = find( st, inf ) )
ans += tans;
}
return ans;
} int main()
{
int T; cin >> T;
while (T--)
{
scanf("%d%d", &N, &M); init();
for (int i = , j = ; i <= M; i++)
{
scanf( "%d%d%d", &num[j], &num[j+], &num[j+] );
addedge1(num[j+],num[j],num[j+]);
j += ;
} scanf("%d%d", &st, &ed); dijkstra(ed);
for ( int i = ; i <= N; i++ )
dised[i] = disst[i];
cnt = ;
memset( linjie1, -, sizeof(linjie1) );
for ( int i = , j = ; i <= M; i++ )
{
addedge1( num[j], num[j+], num[j+] );
j += ;
}
dijkstra(st);
make_map(); printf( "%d\n", dinic() );
}
return ;
}

kuangbin带我飞QAQ 最短路的更多相关文章

  1. kuangbin带我飞QAQ 线段树

    1. HDU1166 裸线段树点修改 #include <iostream> #include <string.h> #include <cstdio> #incl ...

  2. kuangbin带我飞QAQ 并查集

    1. POJ 2236 给出N个点,一开始图是空白的,两个操作,一个是增加一个点(给出坐标),一个是查询两个点间是否相通,当两点间的距离小于D或者两点通过其他点间接相连时说这两个点相通.并查集维护,每 ...

  3. kuangbin带我飞QAQ DLX之一脸懵逼

    1. hust 1017 DLX精确覆盖 模板题 勉强写了注释,但还是一脸懵逼,感觉插入方式明显有问题但又不知道哪里不对而且好像能得出正确结果真是奇了怪了 #include <iostream& ...

  4. kuangbin带你飞 最短路 题解

    求一个图最短路边的办法.好像下面的那个有问题.单向边和双向边一定是有区别的.这个比较容易.参照该文的最短路网络流题目和连通图题目一题求最短路关节边 另外上述2个题目的代码好像有问题. 在UVALIVE ...

  5. 最短路(代码来源于kuangbin和百度)

    最短路 最短路有多种算法,常见的有一下几种:Dijstra.Floyd.Bellman-Ford,其中Dijstra和Bellman-Ford还有优化:Dijstra可以用优先队列(或者堆)优化,Be ...

  6. cdoj 秋实大哥带我飞 最短路走法 含0权边

    //做完这题以后终于理解白书上的边为什么要那样定义了 可以很方便的在o(1) 时间内找到反向边 解法:先跑一边最短路,然后检查最短路上有没有0权边(dfs就好,但是每条边只能走一次,这里就需要用异或找 ...

  7. [kuangbin带你飞]专题四 最短路练习 POJ 3268 Silver Cow Party

    题意: 在一个有向图中求n头牛从自己的起点走到x再从x走回来的最远距离 思路一开始是暴力跑dij…… 讲道理不太可能…… 然后就百度了一下 才知道把矩阵转置的话就只需要求两次x的单源最短路…… /* ...

  8. [ An Ac a Day ^_^ ] [kuangbin带你飞]专题四 最短路练习 POJ 2387 Til the Cows Come Home

    求1到N的最短路 注意有重边 跑一遍dijkstra就行 /* *********************************************** Author :Sun Yuefeng ...

  9. 【算法系列学习】SPFA邻接表最短路 [kuangbin带你飞]专题四 最短路练习 F - Wormholes

    https://vjudge.net/contest/66569#problem/F 题意:判断图中是否存在负权回路 首先,介绍图的邻接表存储方式 数据结构:图的存储结构之邻接表 邻接表建图,类似于头 ...

随机推荐

  1. Java性能优化的50个细节,我必须分享给你!

    来源:blog.csdn.net/dongnan591172113/article/details/51790428 ;i<list.size();i++) ,len=list.size();i ...

  2. axios解决调用后端接口跨域问题

    vue-cli通过是本地代理的方式解决接口跨域问题的.但是在vue-cli的默认项目配置中这个代理是没有配置的,如果现在项目中使用,必须手动配置config/index.js文件 ... proxyT ...

  3. 面试系列17 redis cluster

    1.redis cluster介绍 redis cluster (1)自动将数据进行分片,每个master上放一部分数据(2)提供内置的高可用支持,部分master不可用时,还是可以继续工作的 在re ...

  4. CSS之Important

    1.important只能用于直接选中,不能用于间接选中 2.通配符选择器选中的标签也是直接选中的 3.!important只能提升被指定的属性的优先级 ,其他属性的优先级不会被提升 4.!impor ...

  5. 课程笔记-lisanke

    1.判断真需求假需求 真需求:所有人都需要的功能 假需求:只有自己需要的功能 2.找到目标用户 ①不要直接询问是否需要这个功能 ②旁敲侧击式提问:用户使用了什么方式?之前都是怎么做的? case:购物 ...

  6. matlab之原始处理图像几何变换

    (一)图像几何变换理论知识 (1)图像的平移与比例 图像的平移很简单,平移前后的坐标分别为(x,y)和(x',y'),则满足的关系式为 x'= x +Tx: y'= y +Ty: 其中Tx与Ty分别为 ...

  7. Luogu P4158 [SCOI2009]粉刷匠(dp+背包)

    P4158 [SCOI2009]粉刷匠 题意 题目描述 \(windy\)有\(N\)条木板需要被粉刷.每条木板被分为\(M\)个格子. 每个格子要被刷成红色或蓝色. \(windy\)每次粉刷,只能 ...

  8. MyBatis与Hibernate

    Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句.mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和s ...

  9. Loadrunner安装与破解【转】

    Loadrunner安装与破解 一.下载 我的LoadRunner 11下载地址是: http://pan.baidu.com/s/1qYFy2DI 二.安装 1.启动安装程序 运行setup.exe ...

  10. 使用Cookie实现用户商品历史浏览记录

    该功能分为四个模块: 1. 获取所有商品并以链接的形式显示 out.write("网站商品: <br/>"); Map<String, Book> book ...