题意:给出一张连通图,起点1终点n,问起点到终点有多少条最短路(边不重合),及最多删掉多少条边后还能通过最短路从起点走到终点。
第一个问题直接在最短路的新图上跑一发最大流,第二个问题在跑最短路的时候记录下最短路中用到最少边的最短路即可。类似hdu 的3416
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define ls rt << 1
#define rs rt << 1 | 1
#define pi acos(-1.0)
#define eps 1e-8
#define asd puts("sdfsdfsdfsdfsdfsdf");
#pragma comment(linker, "/STACK:1024000000,1024000000") "")
typedef long long ll;
//typedef __int64 LL;
const int inf = 0x3f3f3f3f;
const int N = 2020;
int st, ed, nv;
struct node{
int nxt, v, w, t;
}e[60010<<1], E[60010<<1], ee[60010<<1];
int head[N], H[N], hh[N];
int cur[N];
int dep[N];
int gap[N];
int s[N], top;
int n, m, cnt, cnt1, cnt2;
queue <int> q;
int ans1, ans2;
struct DIS{
int id, x, t;
bool operator < (const DIS &rhs) const {
return x < rhs.x;
}
}dis[N], dis1[N];
void init()
{
cnt2 = cnt = cnt1 = 0;
memset( H, -1, sizeof( H ) );
memset( head, -1, sizeof( head ) );
memset( hh, -1, sizeof( hh ) );
st = 1, ed = n, nv = ed+1;
}
void add( int u, int v, int w )
{
e[cnt].w = w;
e[cnt].v = v;
e[cnt].nxt = head[u];
head[u] = cnt++;
e[cnt].w = 0;
e[cnt].v = u;
e[cnt].nxt = head[v];
head[v] = cnt++;
}
void add1( int u, int v, int w, int t = 1 )
{
E[cnt1].v = v;
E[cnt1].t = t;
E[cnt1].w = w;
E[cnt1].nxt = H[u];
H[u] = cnt1++;
}
void add2( int u, int v, int w )
{
ee[cnt2].v = v;
ee[cnt2].w = w;
ee[cnt2].nxt = hh[u];
hh[u] = cnt2++;
}
void rev_bfs()
{
while( !q.empty() ) q.pop();
memset( dep, -1, sizeof( dep ) );
memset( gap, 0, sizeof( gap ) );
dep[ed] = 0;
gap[0] = 1;
q.push( ed );
while( !q.empty() ) {
int u = q.front();
q.pop();
for( int i = head[u]; ~i; i = e[i].nxt ) {
int v = e[i].v;
if( ~dep[v] )
continue;
dep[v] = dep[u] + 1;
gap[dep[v]]++;
q.push( v );
}
}
}
int isap()
{
memcpy( cur, head, sizeof cur );
rev_bfs();
int flow = 0, u = st, i;
top = 0;
while( dep[st] < nv ) {
if( u == ed ) {
int minn = inf, tmp;
for( i = 0; i < top; ++i ) {
if( minn > e[s[i]].w ) {
minn = e[s[i]].w;
tmp = i;
}
}
for( i = 0; i < top; ++i ) {
e[s[i]].w -= minn;
e[s[i]^1].w += minn;
}
flow += minn;
top = tmp;
u = e[s[top]^1].v;
}
for( i = cur[u]; ~i; i = e[i].nxt ) {
int v = e[i].v;
if( e[i].w > 0 && dep[u] == dep[v] + 1 ) {
cur[u] = i;
break;
}
}
if( ~i ) {
s[top++] = i;
u = e[i].v;
}
else {
if( 0 == (--gap[dep[u]]) )
break;
int minn = nv;
for( i = head[u]; ~i; i = e[i].nxt ) {
int v = e[i].v;
if( e[i].w > 0 && minn > dep[v] ) {
minn = dep[v];
cur[u] = i;
}
}
dep[u] = minn + 1;
gap[dep[u]]++;
if( u != st ) {
u = e[s[--top]^1].v;
}
}
}
return flow;
}
int read()
{
char ch=' ';
int ans=0;
while(ch<'0' || ch>'9')
ch=getchar();
while(ch<='9' && ch>='0')
{
ans=ans*10+ch-'0';
ch=getchar();
}
return ans;
}
queue <DIS> Q;
void dijkstra( )
{
for( int i = 1; i <= n; ++i ) {
dis[i].id = i;
dis[i].t = dis[i].x = inf;
}
while( !Q.empty() ) Q.pop();
dis[st].t = dis[st].x = 0;
Q.push( dis[st] );
while( !Q.empty() ) {
DIS tmp = Q.front();
Q.pop();
int u = tmp.id, x = tmp.x, t = tmp.t;
for( int i = H[u]; ~i; i = E[i].nxt ) {
int v = E[i].v, w = E[i].w;
if( x + w < dis[v].x ) {
dis[v].t = t + E[i].t;
dis[v].x = x + w;
Q.push( dis[v] );
}
else if( x + w == dis[v].x && t + E[i].t < dis[v].t ) {
dis[v].t = t + E[i].t;
Q.push( dis[v] );
}
}
}
//printf("%d\n", dis[ed].x);
}
void rev_dijkstra( )
{
for( int i = 1; i <= n; ++i ) {
dis1[i].id = i;
dis1[i].x = inf;
}
while( !Q.empty() ) Q.pop();
dis1[ed].x = 0;
Q.push( dis1[ed] );
while( !Q.empty() ) {
DIS tmp = Q.front();
Q.pop();
int u = tmp.id, x = tmp.x;
for( int i = hh[u]; ~i; i = ee[i].nxt ) {
int v = ee[i].v, w = ee[i].w;
if( x + w < dis1[v].x ) {
dis1[v].x = x + w;
Q.push( dis1[v] );
}
}
}
//printf("%d\n", dis1[st].x);
}
void build()
{
int dis_st_ed = dis[ed].x;
for( int u = 1; u <= n; ++u ) {
for( int i = H[u]; ~i; i = E[i].nxt ) {
int v = E[i].v, w = E[i].w;
if( dis[u].x + w + dis1[v].x == dis_st_ed ) {
add( u, v, 1 );
}
}
}
}
int main()
{
while( ~scanf("%d%d", &n, &m ) ) {
init();
for( int i = 1, v, w, u; i <= m; ++i ) {
//scanf("%d%d%d", &u, &v, &w);
u = read();
v = read();
w = read();
if( u == v )
continue;
add1( u, v, w );
add1( v, u, w );
add2( v, u, w );
add2( u, v, w );
}
dijkstra();
rev_dijkstra();
build();
ans1 = isap();
printf("%d %d\n", ans1, m - dis[ed].t);
}
return 0;
}