HDU 6321 Dynamic Graph Matching & 6331 Walking Plan (DP)

hdu6321 对一个图进行加边或删边操作(n<=10),在每次操作后求图的匹配数为k的方案数,其中k=1,2,...n/2。

由于点的数目很少,考虑状压dp,dp[k][i]表示第k次操作后在i状态下点集中最大匹配的方案数,显然对于x个点的状态匹配数最多是x/2个。

考虑加边u-v的操作,如果对于一个状态pre,状态中没有u和v两个点,那么就可以从pre状态转移到now状态,其中now是pre以及u和v的并。删除边的时候同理。可以看到这里转移的时候只需要前一次操作的结果,于是可以使用滚动数组减小空间的使用。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define maxn 10050
#define INF 0x3f3f3f3f
#define eps 1e-8
using namespace std;
typedef long long ll;
const ll mod = 1000000007;

int t,n,m,u,v,cnt;
char s[5];
ll dp[2][maxn],ans[maxn];
int num[maxn],sta[maxn];
int val[15];

void init()
{
    cnt = 0;
    val[0] = 1;
    for(int i = 1;i <= 10;i++)val[i] = val[i-1] * 2;
    for(int i = 0;i < 1024;i++)
    {
        num[i] = num[i>>1] + (i&1);
        if(num[i]%2==0)
            sta[cnt++] = i;
    }
}

int main()
{
    scanf("%d",&t);
    init();
    while(t--)
    {
        scanf("%d%d",&n,&m);
        int now = 0;
        memset(dp,0,sizeof(dp));
        dp[0][0] = 1;
        for(int j = 0;j < m;j++)
        {
            scanf("%s%d%d",s,&u,&v);
            u--,v--;
            int tmp = (val[u] | val[v]);
            memset(ans,0,sizeof(ans));
            for(int i = 0;i < cnt && sta[i] < (1<

hdu6331 给出一个n个点和m条边的图,要求q次查询,每次查询从s到t经过不少于k条边(可重复)的最短距离。n<=50,m,k<=10000,q<=100000。

 显然要先预处理点之间的距离,直接处理的复杂度是O(n^3*m),是无法接受的,考虑一个分块的dp。

dp[i][j][k]表示从i到j恰好经过k条边的最短距离

dp1[i][j][k]表示从i到j至少经过k条边的最短距离

dp2[i][j][k]表示从i到j恰好经过k*100条边的最短距离 ,k<=100

dp[i][j][k]用原图就可以处理出来,而dp1[i][j][k]=min(dp[i][t][k]+dis[t][j]),其中dis[][]是原图处理出的传递闭包。

以及dp2[i][j][k]=min(dp2[i][t][k-1]+dp[k][j][100])。

最后查询时枚举中间点e,ans=min(dp2[i][e][k/100]+dp1[e][t][k%100])。

#include
#include
#include
#include
#define maxn 51
#define maxm 102
#define INF 0x3f3f3f3f
#define eps 1e-8
using namespace std;
typedef long long ll;

int kase,s,e,t,n,m,q,a,b,x;
int dis[maxn][maxn];
int maze[maxn][maxn];
int dp[maxn][maxn][maxm];
int dp1[maxn][maxn][maxm];
int dp2[maxn][maxn][maxm];
//0 k个 1 至少k 2 k*100个
int Min(int a,int b)
{
    if(a < 0)return b;
    else if(b < 0)return a;
    return a

 

你可能感兴趣的:(ACM-ICPC)