Police Cities


Time Limit: 10 Seconds      Memory Limit: 32768 KB

Once upon the time there lived a king and he had a big kingdom. And there were n cities in his kingdom and some of them were connected by the roads. And the roads were all one-way because it would be dangerous if two carriages riding in opposite directions met on a road.

And once the king decided that he would like to establish police in his country and ordered to build police stations in some cities. But since his finances are limited, he would only like build police stations in k different cities. He would like to build them in such a way, that the following conditions were satisfied:

  • it is possible to get by the roads from each city to some city with the police station;
  • it is possible to get by the roads to each city from some city with the police station.

Now the king wants to know how many different ways are there to do so. Help him to find the answer to this question.

Input

There are mutilple cases in the input file.

The first line of each case contains n , m and k --- the number of cities and roads in the kingdom, and the number of police stations to build, respectively (1 <= n <= 100 , 0 <= m <= 20,000 , 1 <= k <= n ). The following m lines contain two city numbers each and describe roads, remember that it is only possible to travel along roads in one direction --- from the first city to the second one. Two cities may be connected by more than one road.

There is an empty line after each case.

Output

Output the only integer number --- the number of ways to fulfil king's request.

There should be an empty line after each case.

Sample Input

6 7 3
1 2
2 3
3 1
3 4
4 5
5 6
6 5

Sample Output

15

Source: Andrew Stankevich's Contest #9

解题:强连通分量缩点后进行dp

首先是入度为0或者出度为0的点必须安排那个警察,dp[i][j]表示前i个入度或者出度为0的强连通分量安排了j个警察

那么有转移方程 $dp[i][j] = \sum_{k = 0}^{k < j} dp[i-1][k]*c[x][j-k]$ 这些分量是必须至少要安置一个警司的,x表示该分量内点的数量

至于其余的,至少安放0个

 #include<bits/stdc++.h>

 using namespace std;

 #define MAXN 100
struct HP {
int len,s[MAXN];
HP() {
memset(s,,sizeof(s));
len=;
}
HP operator =(const char *num) { //字符串赋值
len=strlen(num);
for(int i=; i<len; i++) s[i]=num[len-i-]-'';
} HP operator =(int num) { //int 赋值
char s[MAXN];
sprintf(s,"%d",num);
*this=s;
return *this;
} HP(int num) {
*this=num;
} HP(const char*num) {
*this=num;
} string str()const { //转化成string
string res="";
for(int i=; i<len; i++) res=(char)(s[i]+'')+res;
if(res=="") res="";
return res;
} HP operator +(const HP& b) const {
HP c;
c.len=;
for(int i=,g=; g||i<max(len,b.len); i++) {
int x=g;
if(i<len) x+=s[i];
if(i<b.len) x+=b.s[i];
c.s[c.len++]=x%;
g=x/;
}
return c;
}
void clean() {
while(len > && !s[len-]) len--;
} HP operator *(const HP& b) {
HP c;
c.len=len+b.len;
for(int i=; i<len; i++)
for(int j=; j<b.len; j++)
c.s[i+j]+=s[i]*b.s[j];
for(int i=; i<c.len-; i++) {
c.s[i+]+=c.s[i]/;
c.s[i]%=;
}
c.clean();
return c;
} HP operator - (const HP& b) {
HP c;
c.len = ;
for(int i=,g=; i<len; i++) {
int x=s[i]-g;
if(i<b.len) x-=b.s[i];
if(x>=) g=;
else {
g=;
x+=;
}
c.s[c.len++]=x;
}
c.clean();
return c;
}
HP operator / (const HP &b) {
HP c, f = ;
for(int i = len-; i >= ; i--) {
f = f*;
f.s[] = s[i];
while(f>=b) {
f =f-b;
c.s[i]++;
}
}
c.len = len;
c.clean();
return c;
}
HP operator % (const HP &b) {
HP r = *this / b;
r = *this - r*b;
return r;
} HP operator /= (const HP &b) {
*this = *this / b;
return *this;
} HP operator %= (const HP &b) {
*this = *this % b;
return *this;
} bool operator < (const HP& b) const {
if(len != b.len) return len < b.len;
for(int i = len-; i >= ; i--)
if(s[i] != b.s[i]) return s[i] < b.s[i];
return false;
} bool operator > (const HP& b) const {
return b < *this;
} bool operator <= (const HP& b) {
return !(b < *this);
} bool operator == (const HP& b) {
return !(b < *this) && !(*this < b);
}
bool operator != (const HP &b) {
return !(*this == b);
}
HP operator += (const HP& b) {
*this = *this + b;
return *this;
}
bool operator >= (const HP &b) {
return *this > b || *this == b;
} }; istream& operator >>(istream &in, HP& x) {
string s;
in >> s;
x = s.c_str();
return in;
} ostream& operator <<(ostream &out, const HP& x) {
out << x.str();
return out;
}
const int maxn = ;
HP dp[maxn][maxn],c[maxn][maxn];
void calc() {
for(int i = ; i < maxn; ++i) {
c[i][] = c[i][i] = ;
for(int j = ; j < i; ++j)
c[i][j] = c[i-][j-] + c[i-][j];
}
}
int low[maxn],dfn[maxn],belong[maxn],bcc_size[maxn],bcc,clk;
vector<int>g[maxn],x,y;
stack<int>stk;
int n,m,K,ind[maxn],outd[maxn];
bool instack[maxn];
void init() {
for(int i = ; i < maxn; ++i) {
dfn[i] = belong[i] = bcc_size[i] = ;
g[i].clear();
instack[i] = false;
ind[i] = outd[i] = ;
}
bcc = clk = ;
while(!stk.empty()) stk.pop();
x.clear();
y.clear();
}
void tarjan(int u) {
dfn[u] = low[u] = ++clk;
stk.push(u);
instack[u] = true;
for(int i = g[u].size() - ; i >= ; --i) {
if(!dfn[g[u][i]]) {
tarjan(g[u][i]);
low[u] = min(low[u],low[g[u][i]]);
} else if(instack[g[u][i]]) low[u] = min(low[u],dfn[g[u][i]]);
}
if(low[u] == dfn[u]) {
bcc++;
int v;
do {
v = stk.top();
stk.pop();
belong[v] = bcc;
bcc_size[bcc]++;
instack[v] = false;
} while(v != u);
}
}
int main() {
calc();
int u,v;
while(~scanf("%d%d%d",&n,&m,&K)) {
init();
memset(dp,,sizeof dp);
for(int i = ; i < m; ++i) {
scanf("%d%d",&u,&v);
g[u].push_back(v);
}
dp[][] = ;
for(int i = ; i <= n; ++i)
if(!dfn[i]) tarjan(i);
for(int i = ; i <= n; ++i) {
for(int j = g[i].size()-; j >= ; --j) {
if(belong[i] == belong[g[i][j]]) continue;
ind[belong[g[i][j]]]++;
outd[belong[i]]++;
}
}
for(int i = ; i <= bcc; ++i)
if(!ind[i] || !outd[i]) x.push_back(i);
else y.push_back(i);
for(int i = ; i <= x.size(); ++i)
for(int j = ; j <= K; ++j)
for(int k = j-; k >= && j - k <= bcc_size[x[i-]]; --k)
dp[i][j] += dp[i-][k]*c[bcc_size[x[i-]]][j - k];
for(int i = x.size()+,t = ; i <= bcc; ++i,++t)
for(int j = x.size(); j <= K; ++j)
for(int k = x.size(); k <= j; ++k)
dp[i][j] += dp[i-][k]*c[bcc_size[y[t]]][j - k];
cout<<dp[bcc][K]<<endl<<endl;
}
return ;
}

ZOJ 2699 Police Cities的更多相关文章

  1. 100211D Police Cities

    传送门 分析 看到这个题我们的第一反应自然是Tarjan缩点,在这之后我们可以发现实际只要在缩点之后所有出度或入度为0的点布置警察局就可以达到要求,我们用dpij表示考虑前i个出度或入度为0的点共布置 ...

  2. 【ZOJ 3200】Police and Thief

    ZOJ 3200 首先我写了个高斯消元,但是消出来了一些奇怪的东西,我就放弃了... 然后只好考虑dp:\(dp[i][j][k]\)表示走到了第i步,到了\((j,k)\)这个节点的概率. 那么答案 ...

  3. 【转载】图论 500题——主要为hdu/poj/zoj

    转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

  4. Codeforces Round #130 (Div. 2) C - Police Station 最短路+dp

    题目链接: http://codeforces.com/problemset/problem/208/C C. Police Station time limit per test:2 seconds ...

  5. ZOJ 3794 Greedy Driver

    两次SPFA 第一关找:从1没有出发点到另一个点的多少是留给油箱 把边反过来再找一遍:重每一个点到终点最少须要多少油 Greedy Driver Time Limit: 2 Seconds       ...

  6. ZOJ 1203 Swordfish 旗鱼 最小生成树,Kruskal算法

    主题链接:problemId=203" target="_blank">ZOJ 1203 Swordfish 旗鱼 Swordfish Time Limit: 2 ...

  7. POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat 二分)

    POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat ...

  8. ZOJ 3946.Highway Project(The 13th Zhejiang Provincial Collegiate Programming Contest.K) SPFA

    ZOJ Problem Set - 3946 Highway Project Time Limit: 2 Seconds      Memory Limit: 65536 KB Edward, the ...

  9. zoj 3747 递推dp

    Attack on Titans Time Limit: 2 Seconds      Memory Limit: 65536 KB Over centuries ago, mankind faced ...

随机推荐

  1. hdu 2205(容斥原理)

    Eddy's爱好 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  2. hdoj-看病要排队

    看病要排队 Problem Description 看病要排队这个是地球人都知道的常识. 不过经过细心的0068的观察,他发现了医院里排队还是有讲究的.0068所去的医院有三个医生(汗,这么少)同时看 ...

  3. codeforces 931E Logical Expression dp

    time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standa ...

  4. EMC 存储管理

    第一章EMC 产品介绍 1.1.         名词介绍 DAE——磁盘笼.用于装载磁盘的柜子. ◆Disk processor enclosure——含磁盘的控制器单元.存储系统的主要设备,内含存 ...

  5. 3.4 存储简单数据的利器——Preferences

    <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="ht ...

  6. 胜利大逃亡(续)(bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1429 #include <stdio.h> #include <queue> #incl ...

  7. php 提交编辑数据没有变,返回0,判断

    php 提交编辑数据没有变,返回0,判断以TP为例子 $edit = D('Brand')->save($data);if($edit == true){ echo "修改成功&quo ...

  8. 复习java基础第七天(反射)

    一:目标 Ø理解 Class 类 Ø理解 Java 的类加载机制 Ø学会使用 ClassLoader 进行类加载 Ø理解反射的机制 Ø掌握 Constructor.Method.Field 类的用法 ...

  9. AI: DL方法与问题空间探索

    所谓问题的解决是生存参数空间的一种状态转移到另外一种状态,而目的状态恰好是主体所希望的.完成这种转换的一系列脚本变化过程叫做场景序列,也叫通路.驱动这一些列场景转换的主体参与过程,被称为主动执行.而主 ...

  10. 【sqli-labs】 less18 POST - Header Injection - Uagent field - Error based (基于错误的用户代理,头部POST注入)

    这次username和password都进行了输入校验 但是ip和uagent没有校验 当我们用admin admin登陆成功后,就会一条插入语句 由于程序无条件的信任了浏览器的header信息,那么 ...